This source file includes following definitions.
- ext2_match
- ext2_find_entry
- ext2_lookup
- ext2_add_entry
- ext2_delete_entry
- ext2_create
- ext2_mknod
- ext2_mkdir
- empty_dir
- ext2_rmdir
- ext2_unlink
- ext2_symlink
- ext2_link
- subdir
- do_ext2_rename
- ext2_rename
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <asm/segment.h>
17
18 #include <linux/errno.h>
19 #include <linux/fs.h>
20 #include <linux/ext2_fs.h>
21 #include <linux/fcntl.h>
22 #include <linux/sched.h>
23 #include <linux/stat.h>
24 #include <linux/string.h>
25 #include <linux/locks.h>
26
27
28
29
30
31
32
33
34
35
36 #define NAMEI_RA_CHUNKS 2
37 #define NAMEI_RA_BLOCKS 4
38 #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
39 #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
40
41
42
43
44 static int ext2_match (int len, const char * const name,
45 struct ext2_dir_entry * de)
46 {
47 if (!de || !de->inode || len > EXT2_NAME_LEN)
48 return 0;
49
50
51
52 if (!len && de->name_len == 1 && (de->name[0] == '.') &&
53 (de->name[1] == '\0'))
54 return 1;
55 if (len != de->name_len)
56 return 0;
57 return !memcmp(name, de->name, len);
58 }
59
60
61
62
63
64
65
66
67
68 static struct buffer_head * ext2_find_entry (struct inode * dir,
69 const char * const name, int namelen,
70 struct ext2_dir_entry ** res_dir)
71 {
72 struct super_block * sb;
73 struct buffer_head * bh_use[NAMEI_RA_SIZE];
74 struct buffer_head * bh_read[NAMEI_RA_SIZE];
75 unsigned long offset;
76 int block, toread, i, err;
77
78 *res_dir = NULL;
79 if (!dir)
80 return NULL;
81 sb = dir->i_sb;
82
83 #ifdef NO_TRUNCATE
84 if (namelen > EXT2_NAME_LEN)
85 return NULL;
86 #else
87 if (namelen > EXT2_NAME_LEN)
88 namelen = EXT2_NAME_LEN;
89 #endif
90
91 memset (bh_use, 0, sizeof (bh_use));
92 toread = 0;
93 for (block = 0; block < NAMEI_RA_SIZE; ++block) {
94 struct buffer_head * bh;
95
96 if ((block << EXT2_BLOCK_SIZE_BITS (sb)) >= dir->i_size)
97 break;
98 bh = ext2_getblk (dir, block, 0, &err);
99 bh_use[block] = bh;
100 if (bh && !bh->b_uptodate)
101 bh_read[toread++] = bh;
102 }
103
104 for (block = 0, offset = 0; offset < dir->i_size; block++) {
105 struct buffer_head * bh;
106 struct ext2_dir_entry * de;
107 char * dlimit;
108
109 if ((block % NAMEI_RA_BLOCKS) == 0 && toread) {
110 ll_rw_block (READ, toread, bh_read);
111 toread = 0;
112 }
113 bh = bh_use[block % NAMEI_RA_SIZE];
114 if (!bh) {
115 ext2_error (sb, "ext2_find_entry",
116 "directory #%lu contains a hole at offset %lu",
117 dir->i_ino, offset);
118 offset += sb->s_blocksize;
119 continue;
120 }
121 wait_on_buffer (bh);
122 if (!bh->b_uptodate) {
123
124
125
126 break;
127 }
128
129 de = (struct ext2_dir_entry *) bh->b_data;
130 dlimit = bh->b_data + sb->s_blocksize;
131 while ((char *) de < dlimit) {
132 if (!ext2_check_dir_entry ("ext2_find_entry", dir,
133 de, bh, offset))
134 goto failure;
135 if (de->inode != 0 && ext2_match (namelen, name, de)) {
136 for (i = 0; i < NAMEI_RA_SIZE; ++i) {
137 if (bh_use[i] != bh)
138 brelse (bh_use[i]);
139 }
140 *res_dir = de;
141 return bh;
142 }
143 offset += de->rec_len;
144 de = (struct ext2_dir_entry *)
145 ((char *) de + de->rec_len);
146 }
147
148 brelse (bh);
149 if (((block + NAMEI_RA_SIZE) << EXT2_BLOCK_SIZE_BITS (sb)) >=
150 dir->i_size)
151 bh = NULL;
152 else
153 bh = ext2_getblk (dir, block + NAMEI_RA_SIZE, 0, &err);
154 bh_use[block % NAMEI_RA_SIZE] = bh;
155 if (bh && !bh->b_uptodate)
156 bh_read[toread++] = bh;
157 }
158
159 failure:
160 for (i = 0; i < NAMEI_RA_SIZE; ++i)
161 brelse (bh_use[i]);
162 return NULL;
163 }
164
165 int ext2_lookup (struct inode * dir, const char * name, int len,
166 struct inode ** result)
167 {
168 unsigned long ino;
169 struct ext2_dir_entry * de;
170 struct buffer_head * bh;
171
172 *result = NULL;
173 if (!dir)
174 return -ENOENT;
175 if (!S_ISDIR(dir->i_mode)) {
176 iput (dir);
177 return -ENOENT;
178 }
179 if (dcache_lookup(dir, name, len, &ino)) {
180 if (!ino) {
181 iput(dir);
182 return -ENOENT;
183 }
184 if (!(*result = iget (dir->i_sb, ino))) {
185 iput (dir);
186 return -EACCES;
187 }
188 iput (dir);
189 return 0;
190 }
191 ino = dir->i_version;
192 if (!(bh = ext2_find_entry (dir, name, len, &de))) {
193 if (ino == dir->i_version)
194 dcache_add(dir, name, len, 0);
195 iput (dir);
196 return -ENOENT;
197 }
198 ino = de->inode;
199 dcache_add(dir, name, len, ino);
200 brelse (bh);
201 if (!(*result = iget (dir->i_sb, ino))) {
202 iput (dir);
203 return -EACCES;
204 }
205 iput (dir);
206 return 0;
207 }
208
209
210
211
212
213
214
215
216
217
218
219 static struct buffer_head * ext2_add_entry (struct inode * dir,
220 const char * name, int namelen,
221 struct ext2_dir_entry ** res_dir,
222 int *err)
223 {
224 unsigned long offset;
225 unsigned short rec_len;
226 struct buffer_head * bh;
227 struct ext2_dir_entry * de, * de1;
228 struct super_block * sb;
229
230 *err = -EINVAL;
231 *res_dir = NULL;
232 if (!dir)
233 return NULL;
234 sb = dir->i_sb;
235 #ifdef NO_TRUNCATE
236 if (namelen > EXT2_NAME_LEN)
237 return NULL;
238 #else
239 if (namelen > EXT2_NAME_LEN)
240 namelen = EXT2_NAME_LEN;
241 #endif
242 if (!namelen)
243 return NULL;
244
245
246
247 if (dir->i_size == 0)
248 {
249 *err = -ENOENT;
250 return NULL;
251 }
252 bh = ext2_bread (dir, 0, 0, err);
253 if (!bh)
254 return NULL;
255 rec_len = EXT2_DIR_REC_LEN(namelen);
256 offset = 0;
257 de = (struct ext2_dir_entry *) bh->b_data;
258 *err = -ENOSPC;
259 while (1) {
260 if ((char *)de >= sb->s_blocksize + bh->b_data) {
261 brelse (bh);
262 bh = NULL;
263 bh = ext2_bread (dir, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, err);
264 if (!bh)
265 return NULL;
266 if (dir->i_size <= offset) {
267 if (dir->i_size == 0) {
268 *err = -ENOENT;
269 return NULL;
270 }
271
272 ext2_debug ("creating next block\n");
273
274 de = (struct ext2_dir_entry *) bh->b_data;
275 de->inode = 0;
276 de->rec_len = sb->s_blocksize;
277 dir->i_size = offset + sb->s_blocksize;
278 dir->i_dirt = 1;
279 } else {
280
281 ext2_debug ("skipping to next block\n");
282
283 de = (struct ext2_dir_entry *) bh->b_data;
284 }
285 }
286 if (!ext2_check_dir_entry ("ext2_add_entry", dir, de, bh,
287 offset)) {
288 *err = -ENOENT;
289 brelse (bh);
290 return NULL;
291 }
292 if (de->inode != 0 && ext2_match (namelen, name, de)) {
293 *err = -EEXIST;
294 brelse (bh);
295 return NULL;
296 }
297 if ((de->inode == 0 && de->rec_len >= rec_len) ||
298 (de->rec_len >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
299 offset += de->rec_len;
300 if (de->inode) {
301 de1 = (struct ext2_dir_entry *) ((char *) de +
302 EXT2_DIR_REC_LEN(de->name_len));
303 de1->rec_len = de->rec_len -
304 EXT2_DIR_REC_LEN(de->name_len);
305 de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
306 de = de1;
307 }
308 de->inode = 0;
309 de->name_len = namelen;
310 memcpy (de->name, name, namelen);
311
312
313
314
315
316
317
318
319
320
321
322 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
323 dir->i_dirt = 1;
324 dir->i_version = ++event;
325 mark_buffer_dirty(bh, 1);
326 *res_dir = de;
327 *err = 0;
328 return bh;
329 }
330 offset += de->rec_len;
331 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
332 }
333 brelse (bh);
334 return NULL;
335 }
336
337
338
339
340
341 static int ext2_delete_entry (struct ext2_dir_entry * dir,
342 struct buffer_head * bh)
343 {
344 struct ext2_dir_entry * de, * pde;
345 int i;
346
347 i = 0;
348 pde = NULL;
349 de = (struct ext2_dir_entry *) bh->b_data;
350 while (i < bh->b_size) {
351 if (!ext2_check_dir_entry ("ext2_delete_entry", NULL,
352 de, bh, i))
353 return -EIO;
354 if (de == dir) {
355 if (pde)
356 pde->rec_len += dir->rec_len;
357 dir->inode = 0;
358 return 0;
359 }
360 i += de->rec_len;
361 pde = de;
362 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
363 }
364 return -ENOENT;
365 }
366
367 int ext2_create (struct inode * dir,const char * name, int len, int mode,
368 struct inode ** result)
369 {
370 struct inode * inode;
371 struct buffer_head * bh;
372 struct ext2_dir_entry * de;
373 int err;
374
375 *result = NULL;
376 if (!dir)
377 return -ENOENT;
378 inode = ext2_new_inode (dir, mode);
379 if (!inode) {
380 iput (dir);
381 return -ENOSPC;
382 }
383 inode->i_op = &ext2_file_inode_operations;
384 inode->i_mode = mode;
385 inode->i_dirt = 1;
386 bh = ext2_add_entry (dir, name, len, &de, &err);
387 if (!bh) {
388 inode->i_nlink--;
389 inode->i_dirt = 1;
390 iput (inode);
391 iput (dir);
392 return err;
393 }
394 de->inode = inode->i_ino;
395 dir->i_version = ++event;
396 dcache_add(dir, de->name, de->name_len, de->inode);
397 mark_buffer_dirty(bh, 1);
398 if (IS_SYNC(dir)) {
399 ll_rw_block (WRITE, 1, &bh);
400 wait_on_buffer (bh);
401 }
402 brelse (bh);
403 iput (dir);
404 *result = inode;
405 return 0;
406 }
407
408 int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
409 int rdev)
410 {
411 struct inode * inode;
412 struct buffer_head * bh;
413 struct ext2_dir_entry * de;
414 int err;
415
416 if (!dir)
417 return -ENOENT;
418 bh = ext2_find_entry (dir, name, len, &de);
419 if (bh) {
420 brelse (bh);
421 iput (dir);
422 return -EEXIST;
423 }
424 inode = ext2_new_inode (dir, mode);
425 if (!inode) {
426 iput (dir);
427 return -ENOSPC;
428 }
429 inode->i_uid = current->fsuid;
430 inode->i_mode = mode;
431 inode->i_op = NULL;
432 if (S_ISREG(inode->i_mode))
433 inode->i_op = &ext2_file_inode_operations;
434 else if (S_ISDIR(inode->i_mode)) {
435 inode->i_op = &ext2_dir_inode_operations;
436 if (dir->i_mode & S_ISGID)
437 inode->i_mode |= S_ISGID;
438 }
439 else if (S_ISLNK(inode->i_mode))
440 inode->i_op = &ext2_symlink_inode_operations;
441 else if (S_ISCHR(inode->i_mode))
442 inode->i_op = &chrdev_inode_operations;
443 else if (S_ISBLK(inode->i_mode))
444 inode->i_op = &blkdev_inode_operations;
445 else if (S_ISFIFO(inode->i_mode))
446 init_fifo(inode);
447 if (S_ISBLK(mode) || S_ISCHR(mode))
448 inode->i_rdev = rdev;
449 inode->i_dirt = 1;
450 bh = ext2_add_entry (dir, name, len, &de, &err);
451 if (!bh) {
452 inode->i_nlink--;
453 inode->i_dirt = 1;
454 iput (inode);
455 iput (dir);
456 return err;
457 }
458 de->inode = inode->i_ino;
459 dir->i_version = ++event;
460 dcache_add(dir, de->name, de->name_len, de->inode);
461 mark_buffer_dirty(bh, 1);
462 if (IS_SYNC(dir)) {
463 ll_rw_block (WRITE, 1, &bh);
464 wait_on_buffer (bh);
465 }
466 brelse (bh);
467 iput (dir);
468 iput (inode);
469 return 0;
470 }
471
472 int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
473 {
474 struct inode * inode;
475 struct buffer_head * bh, * dir_block;
476 struct ext2_dir_entry * de;
477 int err;
478
479 if (!dir)
480 return -ENOENT;
481 bh = ext2_find_entry (dir, name, len, &de);
482 if (bh) {
483 brelse (bh);
484 iput (dir);
485 return -EEXIST;
486 }
487 if (dir->i_nlink >= EXT2_LINK_MAX) {
488 iput (dir);
489 return -EMLINK;
490 }
491 inode = ext2_new_inode (dir, S_IFDIR);
492 if (!inode) {
493 iput (dir);
494 return -ENOSPC;
495 }
496 inode->i_op = &ext2_dir_inode_operations;
497 inode->i_size = inode->i_sb->s_blocksize;
498 dir_block = ext2_bread (inode, 0, 1, &err);
499 if (!dir_block) {
500 iput (dir);
501 inode->i_nlink--;
502 inode->i_dirt = 1;
503 iput (inode);
504 return err;
505 }
506 inode->i_blocks = inode->i_sb->s_blocksize / 512;
507 de = (struct ext2_dir_entry *) dir_block->b_data;
508 de->inode = inode->i_ino;
509 de->name_len = 1;
510 de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
511 strcpy (de->name, ".");
512 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
513 de->inode = dir->i_ino;
514 de->rec_len = inode->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1);
515 de->name_len = 2;
516 strcpy (de->name, "..");
517 inode->i_nlink = 2;
518 mark_buffer_dirty(dir_block, 1);
519 brelse (dir_block);
520 inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->fs->umask);
521 if (dir->i_mode & S_ISGID)
522 inode->i_mode |= S_ISGID;
523 inode->i_dirt = 1;
524 bh = ext2_add_entry (dir, name, len, &de, &err);
525 if (!bh) {
526 iput (dir);
527 inode->i_nlink = 0;
528 inode->i_dirt = 1;
529 iput (inode);
530 return err;
531 }
532 de->inode = inode->i_ino;
533 dir->i_version = ++event;
534 dcache_add(dir, de->name, de->name_len, de->inode);
535 mark_buffer_dirty(bh, 1);
536 if (IS_SYNC(dir)) {
537 ll_rw_block (WRITE, 1, &bh);
538 wait_on_buffer (bh);
539 }
540 dir->i_nlink++;
541 dir->i_dirt = 1;
542 iput (dir);
543 iput (inode);
544 brelse (bh);
545 return 0;
546 }
547
548
549
550
551 static int empty_dir (struct inode * inode)
552 {
553 unsigned long offset;
554 struct buffer_head * bh;
555 struct ext2_dir_entry * de, * de1;
556 struct super_block * sb;
557 int err;
558
559 sb = inode->i_sb;
560 if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
561 !(bh = ext2_bread (inode, 0, 0, &err))) {
562 ext2_warning (inode->i_sb, "empty_dir",
563 "bad directory (dir #%lu) - no data block",
564 inode->i_ino);
565 return 1;
566 }
567 de = (struct ext2_dir_entry *) bh->b_data;
568 de1 = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
569 if (de->inode != inode->i_ino || !de1->inode ||
570 strcmp (".", de->name) || strcmp ("..", de1->name)) {
571 ext2_warning (inode->i_sb, "empty_dir",
572 "bad directory (dir #%lu) - no `.' or `..'",
573 inode->i_ino);
574 return 1;
575 }
576 offset = de->rec_len + de1->rec_len;
577 de = (struct ext2_dir_entry *) ((char *) de1 + de1->rec_len);
578 while (offset < inode->i_size ) {
579 if ((void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
580 brelse (bh);
581 bh = ext2_bread (inode, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, &err);
582 if (!bh) {
583 ext2_error (sb, "empty_dir",
584 "directory #%lu contains a hole at offset %lu",
585 inode->i_ino, offset);
586 offset += sb->s_blocksize;
587 continue;
588 }
589 de = (struct ext2_dir_entry *) bh->b_data;
590 }
591 if (!ext2_check_dir_entry ("empty_dir", inode, de, bh,
592 offset)) {
593 brelse (bh);
594 return 1;
595 }
596 if (de->inode) {
597 brelse (bh);
598 return 0;
599 }
600 offset += de->rec_len;
601 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
602 }
603 brelse (bh);
604 return 1;
605 }
606
607 int ext2_rmdir (struct inode * dir, const char * name, int len)
608 {
609 int retval;
610 struct inode * inode;
611 struct buffer_head * bh;
612 struct ext2_dir_entry * de;
613
614 repeat:
615 if (!dir)
616 return -ENOENT;
617 inode = NULL;
618 bh = ext2_find_entry (dir, name, len, &de);
619 retval = -ENOENT;
620 if (!bh)
621 goto end_rmdir;
622 retval = -EPERM;
623 if (!(inode = iget (dir->i_sb, de->inode)))
624 goto end_rmdir;
625 if (inode->i_dev != dir->i_dev)
626 goto end_rmdir;
627 if (de->inode != inode->i_ino) {
628 iput(inode);
629 brelse(bh);
630 current->counter = 0;
631 schedule();
632 goto repeat;
633 }
634 if ((dir->i_mode & S_ISVTX) && !fsuser() &&
635 current->fsuid != inode->i_uid &&
636 current->fsuid != dir->i_uid)
637 goto end_rmdir;
638 if (inode == dir)
639 goto end_rmdir;
640 if (!S_ISDIR(inode->i_mode)) {
641 retval = -ENOTDIR;
642 goto end_rmdir;
643 }
644 down(&inode->i_sem);
645 if (!empty_dir (inode))
646 retval = -ENOTEMPTY;
647 else if (de->inode != inode->i_ino)
648 retval = -ENOENT;
649 else {
650 if (inode->i_count > 1) {
651
652
653
654
655
656
657
658 inode->i_size = 0;
659 }
660 retval = ext2_delete_entry (de, bh);
661 dir->i_version = ++event;
662 }
663 up(&inode->i_sem);
664 if (retval)
665 goto end_rmdir;
666 mark_buffer_dirty(bh, 1);
667 if (IS_SYNC(dir)) {
668 ll_rw_block (WRITE, 1, &bh);
669 wait_on_buffer (bh);
670 }
671 if (inode->i_nlink != 2)
672 ext2_warning (inode->i_sb, "ext2_rmdir",
673 "empty directory has nlink!=2 (%d)",
674 inode->i_nlink);
675 inode->i_version = ++event;
676 inode->i_nlink = 0;
677 inode->i_dirt = 1;
678 dir->i_nlink--;
679 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
680 dir->i_dirt = 1;
681 end_rmdir:
682 iput (dir);
683 iput (inode);
684 brelse (bh);
685 return retval;
686 }
687
688 int ext2_unlink (struct inode * dir, const char * name, int len)
689 {
690 int retval;
691 struct inode * inode;
692 struct buffer_head * bh;
693 struct ext2_dir_entry * de;
694
695 repeat:
696 if (!dir)
697 return -ENOENT;
698 retval = -ENOENT;
699 inode = NULL;
700 bh = ext2_find_entry (dir, name, len, &de);
701 if (!bh)
702 goto end_unlink;
703 if (!(inode = iget (dir->i_sb, de->inode)))
704 goto end_unlink;
705 retval = -EPERM;
706 if (S_ISDIR(inode->i_mode))
707 goto end_unlink;
708 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
709 goto end_unlink;
710 if (de->inode != inode->i_ino) {
711 iput(inode);
712 brelse(bh);
713 current->counter = 0;
714 schedule();
715 goto repeat;
716 }
717 if ((dir->i_mode & S_ISVTX) && !fsuser() &&
718 current->fsuid != inode->i_uid &&
719 current->fsuid != dir->i_uid)
720 goto end_unlink;
721 if (!inode->i_nlink) {
722 ext2_warning (inode->i_sb, "ext2_unlink",
723 "Deleting nonexistent file (%lu), %d",
724 inode->i_ino, inode->i_nlink);
725 inode->i_nlink = 1;
726 }
727 retval = ext2_delete_entry (de, bh);
728 if (retval)
729 goto end_unlink;
730 dir->i_version = ++event;
731 mark_buffer_dirty(bh, 1);
732 if (IS_SYNC(dir)) {
733 ll_rw_block (WRITE, 1, &bh);
734 wait_on_buffer (bh);
735 }
736 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
737 dir->i_dirt = 1;
738 inode->i_nlink--;
739 inode->i_dirt = 1;
740 inode->i_ctime = dir->i_ctime;
741 retval = 0;
742 end_unlink:
743 brelse (bh);
744 iput (inode);
745 iput (dir);
746 return retval;
747 }
748
749 int ext2_symlink (struct inode * dir, const char * name, int len,
750 const char * symname)
751 {
752 struct ext2_dir_entry * de;
753 struct inode * inode = NULL;
754 struct buffer_head * bh = NULL, * name_block = NULL;
755 char * link;
756 int i, err;
757 int l;
758 char c;
759
760 if (!(inode = ext2_new_inode (dir, S_IFLNK))) {
761 iput (dir);
762 return -ENOSPC;
763 }
764 inode->i_mode = S_IFLNK | S_IRWXUGO;
765 inode->i_op = &ext2_symlink_inode_operations;
766 for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
767 symname [l]; l++)
768 ;
769 if (l >= sizeof (inode->u.ext2_i.i_data)) {
770
771 ext2_debug ("l=%d, normal symlink\n", l);
772
773 name_block = ext2_bread (inode, 0, 1, &err);
774 if (!name_block) {
775 iput (dir);
776 inode->i_nlink--;
777 inode->i_dirt = 1;
778 iput (inode);
779 return err;
780 }
781 link = name_block->b_data;
782 } else {
783 link = (char *) inode->u.ext2_i.i_data;
784
785 ext2_debug ("l=%d, fast symlink\n", l);
786
787 }
788 i = 0;
789 while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
790 link[i++] = c;
791 link[i] = 0;
792 if (name_block) {
793 mark_buffer_dirty(name_block, 1);
794 brelse (name_block);
795 }
796 inode->i_size = i;
797 inode->i_dirt = 1;
798 bh = ext2_find_entry (dir, name, len, &de);
799 if (bh) {
800 inode->i_nlink--;
801 inode->i_dirt = 1;
802 iput (inode);
803 brelse (bh);
804 iput (dir);
805 return -EEXIST;
806 }
807 bh = ext2_add_entry (dir, name, len, &de, &err);
808 if (!bh) {
809 inode->i_nlink--;
810 inode->i_dirt = 1;
811 iput (inode);
812 iput (dir);
813 return err;
814 }
815 de->inode = inode->i_ino;
816 dir->i_version = ++event;
817 dcache_add(dir, de->name, de->name_len, de->inode);
818 mark_buffer_dirty(bh, 1);
819 if (IS_SYNC(dir)) {
820 ll_rw_block (WRITE, 1, &bh);
821 wait_on_buffer (bh);
822 }
823 brelse (bh);
824 iput (dir);
825 iput (inode);
826 return 0;
827 }
828
829 int ext2_link (struct inode * oldinode, struct inode * dir,
830 const char * name, int len)
831 {
832 struct ext2_dir_entry * de;
833 struct buffer_head * bh;
834 int err;
835
836 if (S_ISDIR(oldinode->i_mode)) {
837 iput (oldinode);
838 iput (dir);
839 return -EPERM;
840 }
841 if (IS_APPEND(oldinode) || IS_IMMUTABLE(oldinode)) {
842 iput (oldinode);
843 iput (dir);
844 return -EPERM;
845 }
846 if (oldinode->i_nlink >= EXT2_LINK_MAX) {
847 iput (oldinode);
848 iput (dir);
849 return -EMLINK;
850 }
851 bh = ext2_find_entry (dir, name, len, &de);
852 if (bh) {
853 brelse (bh);
854 iput (dir);
855 iput (oldinode);
856 return -EEXIST;
857 }
858 bh = ext2_add_entry (dir, name, len, &de, &err);
859 if (!bh) {
860 iput (dir);
861 iput (oldinode);
862 return err;
863 }
864 de->inode = oldinode->i_ino;
865 dir->i_version = ++event;
866 dcache_add(dir, de->name, de->name_len, de->inode);
867 mark_buffer_dirty(bh, 1);
868 if (IS_SYNC(dir)) {
869 ll_rw_block (WRITE, 1, &bh);
870 wait_on_buffer (bh);
871 }
872 brelse (bh);
873 iput (dir);
874 oldinode->i_nlink++;
875 oldinode->i_ctime = CURRENT_TIME;
876 oldinode->i_dirt = 1;
877 iput (oldinode);
878 return 0;
879 }
880
881 static int subdir (struct inode * new_inode, struct inode * old_inode)
882 {
883 int ino;
884 int result;
885
886 new_inode->i_count++;
887 result = 0;
888 for (;;) {
889 if (new_inode == old_inode) {
890 result = 1;
891 break;
892 }
893 if (new_inode->i_dev != old_inode->i_dev)
894 break;
895 ino = new_inode->i_ino;
896 if (ext2_lookup (new_inode, "..", 2, &new_inode))
897 break;
898 if (new_inode->i_ino == ino)
899 break;
900 }
901 iput (new_inode);
902 return result;
903 }
904
905 #define PARENT_INO(buffer) \
906 ((struct ext2_dir_entry *) ((char *) buffer + \
907 ((struct ext2_dir_entry *) buffer)->rec_len))->inode
908
909 #define PARENT_NAME(buffer) \
910 ((struct ext2_dir_entry *) ((char *) buffer + \
911 ((struct ext2_dir_entry *) buffer)->rec_len))->name
912
913
914
915
916
917
918
919
920
921
922
923
924 static int do_ext2_rename (struct inode * old_dir, const char * old_name,
925 int old_len, struct inode * new_dir,
926 const char * new_name, int new_len)
927 {
928 struct inode * old_inode, * new_inode;
929 struct buffer_head * old_bh, * new_bh, * dir_bh;
930 struct ext2_dir_entry * old_de, * new_de;
931 int retval;
932
933 goto start_up;
934 try_again:
935 if (new_bh && new_de) {
936 ext2_delete_entry(new_de, new_bh);
937 new_dir->i_version = ++event;
938 }
939 brelse (old_bh);
940 brelse (new_bh);
941 brelse (dir_bh);
942 iput (old_inode);
943 iput (new_inode);
944 current->counter = 0;
945 schedule ();
946 start_up:
947 old_inode = new_inode = NULL;
948 old_bh = new_bh = dir_bh = NULL;
949 new_de = NULL;
950 old_bh = ext2_find_entry (old_dir, old_name, old_len, &old_de);
951 retval = -ENOENT;
952 if (!old_bh)
953 goto end_rename;
954 old_inode = __iget (old_dir->i_sb, old_de->inode, 0);
955 if (!old_inode)
956 goto end_rename;
957 retval = -EPERM;
958 if ((old_dir->i_mode & S_ISVTX) &&
959 current->fsuid != old_inode->i_uid &&
960 current->fsuid != old_dir->i_uid && !fsuser())
961 goto end_rename;
962 if (IS_APPEND(old_inode) || IS_IMMUTABLE(old_inode))
963 goto end_rename;
964 new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de);
965 if (new_bh) {
966 new_inode = __iget (new_dir->i_sb, new_de->inode, 0);
967 if (!new_inode) {
968 brelse (new_bh);
969 new_bh = NULL;
970 }
971 }
972 if (new_inode == old_inode) {
973 retval = 0;
974 goto end_rename;
975 }
976 if (new_inode && S_ISDIR(new_inode->i_mode)) {
977 retval = -EISDIR;
978 if (!S_ISDIR(old_inode->i_mode))
979 goto end_rename;
980 retval = -EINVAL;
981 if (subdir (new_dir, old_inode))
982 goto end_rename;
983 retval = -ENOTEMPTY;
984 if (!empty_dir (new_inode))
985 goto end_rename;
986 retval = -EBUSY;
987 if (new_inode->i_count > 1)
988 goto end_rename;
989 }
990 retval = -EPERM;
991 if (new_inode && (new_dir->i_mode & S_ISVTX) &&
992 current->fsuid != new_inode->i_uid &&
993 current->fsuid != new_dir->i_uid && !fsuser())
994 goto end_rename;
995 if (S_ISDIR(old_inode->i_mode)) {
996 retval = -ENOTDIR;
997 if (new_inode && !S_ISDIR(new_inode->i_mode))
998 goto end_rename;
999 retval = -EINVAL;
1000 if (subdir (new_dir, old_inode))
1001 goto end_rename;
1002 dir_bh = ext2_bread (old_inode, 0, 0, &retval);
1003 if (!dir_bh)
1004 goto end_rename;
1005 if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
1006 goto end_rename;
1007 retval = -EMLINK;
1008 if (!new_inode && new_dir->i_nlink >= EXT2_LINK_MAX)
1009 goto end_rename;
1010 }
1011 if (!new_bh)
1012 new_bh = ext2_add_entry (new_dir, new_name, new_len, &new_de,
1013 &retval);
1014 if (!new_bh)
1015 goto end_rename;
1016 new_dir->i_version = ++event;
1017
1018
1019
1020 if (new_inode && (new_de->inode != new_inode->i_ino))
1021 goto try_again;
1022 if (new_de->inode && !new_inode)
1023 goto try_again;
1024 if (old_de->inode != old_inode->i_ino)
1025 goto try_again;
1026
1027
1028
1029 new_de->inode = old_inode->i_ino;
1030 dcache_add(new_dir, new_de->name, new_de->name_len, new_de->inode);
1031 retval = ext2_delete_entry (old_de, old_bh);
1032 if (retval == -ENOENT)
1033 goto try_again;
1034 if (retval)
1035 goto end_rename;
1036 old_dir->i_version = ++event;
1037 if (new_inode) {
1038 new_inode->i_nlink--;
1039 new_inode->i_ctime = CURRENT_TIME;
1040 new_inode->i_dirt = 1;
1041 }
1042 old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
1043 old_dir->i_dirt = 1;
1044 if (dir_bh) {
1045 PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
1046 dcache_add(old_inode, "..", 2, new_dir->i_ino);
1047 mark_buffer_dirty(dir_bh, 1);
1048 old_dir->i_nlink--;
1049 old_dir->i_dirt = 1;
1050 if (new_inode) {
1051 new_inode->i_nlink--;
1052 new_inode->i_dirt = 1;
1053 } else {
1054 new_dir->i_nlink++;
1055 new_dir->i_dirt = 1;
1056 }
1057 }
1058 mark_buffer_dirty(old_bh, 1);
1059 if (IS_SYNC(old_dir)) {
1060 ll_rw_block (WRITE, 1, &old_bh);
1061 wait_on_buffer (old_bh);
1062 }
1063 mark_buffer_dirty(new_bh, 1);
1064 if (IS_SYNC(new_dir)) {
1065 ll_rw_block (WRITE, 1, &new_bh);
1066 wait_on_buffer (new_bh);
1067 }
1068 retval = 0;
1069 end_rename:
1070 brelse (dir_bh);
1071 brelse (old_bh);
1072 brelse (new_bh);
1073 iput (old_inode);
1074 iput (new_inode);
1075 iput (old_dir);
1076 iput (new_dir);
1077 return retval;
1078 }
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 int ext2_rename (struct inode * old_dir, const char * old_name, int old_len,
1094 struct inode * new_dir, const char * new_name, int new_len)
1095 {
1096 int result;
1097
1098 while (old_dir->i_sb->u.ext2_sb.s_rename_lock)
1099 sleep_on (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1100 old_dir->i_sb->u.ext2_sb.s_rename_lock = 1;
1101 result = do_ext2_rename (old_dir, old_name, old_len, new_dir,
1102 new_name, new_len);
1103 old_dir->i_sb->u.ext2_sb.s_rename_lock = 0;
1104 wake_up (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1105 return result;
1106 }