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