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 dir->i_version++;
394 #ifndef DONT_USE_DCACHE
395 ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
396 de->inode);
397 #endif
398 mark_buffer_dirty(bh, 1);
399 if (IS_SYNC(dir)) {
400 ll_rw_block (WRITE, 1, &bh);
401 wait_on_buffer (bh);
402 }
403 brelse (bh);
404 iput (dir);
405 *result = inode;
406 return 0;
407 }
408
409 int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
410 int rdev)
411 {
412 struct inode * inode;
413 struct buffer_head * bh;
414 struct ext2_dir_entry * de;
415 int err;
416
417 if (!dir)
418 return -ENOENT;
419 bh = ext2_find_entry (dir, name, len, &de);
420 if (bh) {
421 brelse (bh);
422 iput (dir);
423 return -EEXIST;
424 }
425 inode = ext2_new_inode (dir, mode);
426 if (!inode) {
427 iput (dir);
428 return -ENOSPC;
429 }
430 inode->i_uid = current->euid;
431 inode->i_mode = mode;
432 inode->i_op = NULL;
433 if (S_ISREG(inode->i_mode))
434 inode->i_op = &ext2_file_inode_operations;
435 else if (S_ISDIR(inode->i_mode)) {
436 inode->i_op = &ext2_dir_inode_operations;
437 if (dir->i_mode & S_ISGID)
438 inode->i_mode |= S_ISGID;
439 }
440 else if (S_ISLNK(inode->i_mode))
441 inode->i_op = &ext2_symlink_inode_operations;
442 else if (S_ISCHR(inode->i_mode))
443 inode->i_op = &chrdev_inode_operations;
444 else if (S_ISBLK(inode->i_mode))
445 inode->i_op = &blkdev_inode_operations;
446 else if (S_ISFIFO(inode->i_mode))
447 init_fifo(inode);
448 if (S_ISBLK(mode) || S_ISCHR(mode))
449 inode->i_rdev = rdev;
450 inode->i_dirt = 1;
451 bh = ext2_add_entry (dir, name, len, &de, &err);
452 if (!bh) {
453 inode->i_nlink--;
454 inode->i_dirt = 1;
455 iput (inode);
456 iput (dir);
457 return err;
458 }
459 de->inode = inode->i_ino;
460 dir->i_version++;
461 #ifndef DONT_USE_DCACHE
462 ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
463 de->inode);
464 #endif
465 mark_buffer_dirty(bh, 1);
466 if (IS_SYNC(dir)) {
467 ll_rw_block (WRITE, 1, &bh);
468 wait_on_buffer (bh);
469 }
470 brelse (bh);
471 iput (dir);
472 iput (inode);
473 return 0;
474 }
475
476 int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
477 {
478 struct inode * inode;
479 struct buffer_head * bh, * dir_block;
480 struct ext2_dir_entry * de;
481 int err;
482
483 if (!dir)
484 return -ENOENT;
485 bh = ext2_find_entry (dir, name, len, &de);
486 if (bh) {
487 brelse (bh);
488 iput (dir);
489 return -EEXIST;
490 }
491 if (dir->i_nlink >= EXT2_LINK_MAX) {
492 iput (dir);
493 return -EMLINK;
494 }
495 inode = ext2_new_inode (dir, S_IFDIR);
496 if (!inode) {
497 iput (dir);
498 return -ENOSPC;
499 }
500 inode->i_op = &ext2_dir_inode_operations;
501 inode->i_size = inode->i_sb->s_blocksize;
502 dir_block = ext2_bread (inode, 0, 1, &err);
503 if (!dir_block) {
504 iput (dir);
505 inode->i_nlink--;
506 inode->i_dirt = 1;
507 iput (inode);
508 return err;
509 }
510 inode->i_blocks = inode->i_sb->s_blocksize / 512;
511 de = (struct ext2_dir_entry *) dir_block->b_data;
512 de->inode = inode->i_ino;
513 de->name_len = 1;
514 de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
515 strcpy (de->name, ".");
516 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
517 de->inode = dir->i_ino;
518 de->rec_len = inode->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1);
519 de->name_len = 2;
520 strcpy (de->name, "..");
521 inode->i_nlink = 2;
522 mark_buffer_dirty(dir_block, 1);
523 brelse (dir_block);
524 inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->fs->umask);
525 if (dir->i_mode & S_ISGID)
526 inode->i_mode |= S_ISGID;
527 inode->i_dirt = 1;
528 bh = ext2_add_entry (dir, name, len, &de, &err);
529 if (!bh) {
530 iput (dir);
531 inode->i_nlink = 0;
532 inode->i_dirt = 1;
533 iput (inode);
534 return err;
535 }
536 de->inode = inode->i_ino;
537 dir->i_version++;
538 #ifndef DONT_USE_DCACHE
539 ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
540 de->inode);
541 #endif
542 mark_buffer_dirty(bh, 1);
543 if (IS_SYNC(dir)) {
544 ll_rw_block (WRITE, 1, &bh);
545 wait_on_buffer (bh);
546 }
547 dir->i_nlink++;
548 dir->i_dirt = 1;
549 iput (dir);
550 iput (inode);
551 brelse (bh);
552 return 0;
553 }
554
555
556
557
558 static int empty_dir (struct inode * inode)
559 {
560 unsigned long offset;
561 struct buffer_head * bh;
562 struct ext2_dir_entry * de, * de1;
563 struct super_block * sb;
564 int err;
565
566 sb = inode->i_sb;
567 if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
568 !(bh = ext2_bread (inode, 0, 0, &err))) {
569 ext2_warning (inode->i_sb, "empty_dir",
570 "bad directory (dir %lu)", inode->i_ino);
571 return 1;
572 }
573 de = (struct ext2_dir_entry *) bh->b_data;
574 de1 = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
575 if (de->inode != inode->i_ino || !de1->inode ||
576 strcmp (".", de->name) || strcmp ("..", de1->name)) {
577 ext2_warning (inode->i_sb, "empty_dir",
578 "bad directory (dir %lu)", inode->i_ino);
579 return 1;
580 }
581 offset = de->rec_len + de1->rec_len;
582 de = (struct ext2_dir_entry *) ((char *) de1 + de1->rec_len);
583 while (offset < inode->i_size ) {
584 if ((void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
585 brelse (bh);
586 bh = ext2_bread (inode, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, &err);
587 if (!bh) {
588 offset += sb->s_blocksize;
589 continue;
590 }
591 de = (struct ext2_dir_entry *) bh->b_data;
592 }
593 if (!ext2_check_dir_entry ("empty_dir", inode, de, bh,
594 offset)) {
595 brelse (bh);
596 return 1;
597 }
598 if (de->inode) {
599 brelse (bh);
600 return 0;
601 }
602 offset += de->rec_len;
603 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
604 }
605 brelse (bh);
606 return 1;
607 }
608
609 int ext2_rmdir (struct inode * dir, const char * name, int len)
610 {
611 int retval;
612 struct inode * inode;
613 struct buffer_head * bh;
614 struct ext2_dir_entry * de;
615
616 repeat:
617 if (!dir)
618 return -ENOENT;
619 inode = NULL;
620 bh = ext2_find_entry (dir, name, len, &de);
621 retval = -ENOENT;
622 if (!bh)
623 goto end_rmdir;
624 retval = -EPERM;
625 if (!(inode = iget (dir->i_sb, de->inode)))
626 goto end_rmdir;
627 if (inode->i_dev != dir->i_dev)
628 goto end_rmdir;
629 if (de->inode != inode->i_ino) {
630 iput(inode);
631 brelse(bh);
632 current->counter = 0;
633 schedule();
634 goto repeat;
635 }
636 if ((dir->i_mode & S_ISVTX) && !suser() &&
637 current->euid != inode->i_uid &&
638 current->euid != dir->i_uid)
639 goto end_rmdir;
640 if (inode == dir)
641 goto end_rmdir;
642 if (!S_ISDIR(inode->i_mode)) {
643 retval = -ENOTDIR;
644 goto end_rmdir;
645 }
646 down(&inode->i_sem);
647 if (!empty_dir (inode))
648 retval = -ENOTEMPTY;
649 else if (de->inode != inode->i_ino)
650 retval = -ENOENT;
651 else {
652 if (inode->i_count > 1) {
653
654
655
656
657
658
659
660 inode->i_size = 0;
661 }
662 retval = ext2_delete_entry (de, bh);
663 dir->i_version++;
664 }
665 up(&inode->i_sem);
666 if (retval)
667 goto end_rmdir;
668 mark_buffer_dirty(bh, 1);
669 if (IS_SYNC(dir)) {
670 ll_rw_block (WRITE, 1, &bh);
671 wait_on_buffer (bh);
672 }
673 #ifndef DONT_USE_DCACHE
674 ext2_dcache_remove(inode->i_dev, inode->i_ino, ".", 1);
675 ext2_dcache_remove(inode->i_dev, inode->i_ino, "..", 2);
676 #endif
677 if (inode->i_nlink != 2)
678 ext2_warning (inode->i_sb, "ext2_rmdir",
679 "empty directory has nlink!=2 (%d)",
680 inode->i_nlink);
681 #ifndef DONT_USE_DCACHE
682 ext2_dcache_remove (dir->i_dev, dir->i_ino, de->name, de->name_len);
683 #endif
684 inode->i_nlink = 0;
685 inode->i_dirt = 1;
686 dir->i_nlink--;
687 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
688 dir->i_dirt = 1;
689 end_rmdir:
690 iput (dir);
691 iput (inode);
692 brelse (bh);
693 return retval;
694 }
695
696 int ext2_unlink (struct inode * dir, const char * name, int len)
697 {
698 int retval;
699 struct inode * inode;
700 struct buffer_head * bh;
701 struct ext2_dir_entry * de;
702
703 repeat:
704 if (!dir)
705 return -ENOENT;
706 retval = -ENOENT;
707 inode = NULL;
708 bh = ext2_find_entry (dir, name, len, &de);
709 if (!bh)
710 goto end_unlink;
711 if (!(inode = iget (dir->i_sb, de->inode)))
712 goto end_unlink;
713 retval = -EPERM;
714 if (S_ISDIR(inode->i_mode))
715 goto end_unlink;
716 if (de->inode != inode->i_ino) {
717 iput(inode);
718 brelse(bh);
719 current->counter = 0;
720 schedule();
721 goto repeat;
722 }
723 if ((dir->i_mode & S_ISVTX) && !suser() &&
724 current->euid != inode->i_uid &&
725 current->euid != dir->i_uid)
726 goto end_unlink;
727 if (!inode->i_nlink) {
728 ext2_warning (inode->i_sb, "ext2_unlink",
729 "Deleting nonexistent file (%lu), %d",
730 inode->i_ino, inode->i_nlink);
731 inode->i_nlink = 1;
732 }
733 retval = ext2_delete_entry (de, bh);
734 if (retval)
735 goto end_unlink;
736 dir->i_version++;
737 mark_buffer_dirty(bh, 1);
738 if (IS_SYNC(dir)) {
739 ll_rw_block (WRITE, 1, &bh);
740 wait_on_buffer (bh);
741 }
742 #ifndef DONT_USE_DCACHE
743 ext2_dcache_remove (dir->i_dev, dir->i_ino, de->name, de->name_len);
744 #endif
745 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
746 dir->i_dirt = 1;
747 inode->i_nlink--;
748 inode->i_dirt = 1;
749 inode->i_ctime = dir->i_ctime;
750 retval = 0;
751 end_unlink:
752 brelse (bh);
753 iput (inode);
754 iput (dir);
755 return retval;
756 }
757
758 int ext2_symlink (struct inode * dir, const char * name, int len,
759 const char * symname)
760 {
761 struct ext2_dir_entry * de;
762 struct inode * inode = NULL;
763 struct buffer_head * bh = NULL, * name_block = NULL;
764 char * link;
765 int i, err;
766 int l;
767 char c;
768
769 if (!(inode = ext2_new_inode (dir, S_IFLNK))) {
770 iput (dir);
771 return -ENOSPC;
772 }
773 inode->i_mode = S_IFLNK | S_IRWXUGO;
774 inode->i_op = &ext2_symlink_inode_operations;
775 for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
776 symname [l]; l++)
777 ;
778 if (l >= EXT2_N_BLOCKS * sizeof (unsigned long)) {
779
780 ext2_debug ("l=%d, normal symlink\n", l);
781
782 name_block = ext2_bread (inode, 0, 1, &err);
783 if (!name_block) {
784 iput (dir);
785 inode->i_nlink--;
786 inode->i_dirt = 1;
787 iput (inode);
788 return err;
789 }
790 link = name_block->b_data;
791 } else {
792 link = (char *) inode->u.ext2_i.i_data;
793
794 ext2_debug ("l=%d, fast symlink\n", l);
795
796 }
797 i = 0;
798 while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
799 link[i++] = c;
800 link[i] = 0;
801 if (name_block) {
802 mark_buffer_dirty(name_block, 1);
803 brelse (name_block);
804 }
805 inode->i_size = i;
806 inode->i_dirt = 1;
807 bh = ext2_find_entry (dir, name, len, &de);
808 if (bh) {
809 inode->i_nlink--;
810 inode->i_dirt = 1;
811 iput (inode);
812 brelse (bh);
813 iput (dir);
814 return -EEXIST;
815 }
816 bh = ext2_add_entry (dir, name, len, &de, &err);
817 if (!bh) {
818 inode->i_nlink--;
819 inode->i_dirt = 1;
820 iput (inode);
821 iput (dir);
822 return err;
823 }
824 de->inode = inode->i_ino;
825 dir->i_version++;
826 #ifndef DONT_USE_DCACHE
827 ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
828 de->inode);
829 #endif
830 mark_buffer_dirty(bh, 1);
831 if (IS_SYNC(dir)) {
832 ll_rw_block (WRITE, 1, &bh);
833 wait_on_buffer (bh);
834 }
835 brelse (bh);
836 iput (dir);
837 iput (inode);
838 return 0;
839 }
840
841 int ext2_link (struct inode * oldinode, struct inode * dir,
842 const char * name, int len)
843 {
844 struct ext2_dir_entry * de;
845 struct buffer_head * bh;
846 int err;
847
848 if (S_ISDIR(oldinode->i_mode)) {
849 iput (oldinode);
850 iput (dir);
851 return -EPERM;
852 }
853 if (oldinode->i_nlink >= EXT2_LINK_MAX) {
854 iput (oldinode);
855 iput (dir);
856 return -EMLINK;
857 }
858 bh = ext2_find_entry (dir, name, len, &de);
859 if (bh) {
860 brelse (bh);
861 iput (dir);
862 iput (oldinode);
863 return -EEXIST;
864 }
865 bh = ext2_add_entry (dir, name, len, &de, &err);
866 if (!bh) {
867 iput (dir);
868 iput (oldinode);
869 return err;
870 }
871 de->inode = oldinode->i_ino;
872 dir->i_version++;
873 #ifndef DONT_USE_DCACHE
874 ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
875 de->inode);
876 #endif
877 mark_buffer_dirty(bh, 1);
878 if (IS_SYNC(dir)) {
879 ll_rw_block (WRITE, 1, &bh);
880 wait_on_buffer (bh);
881 }
882 brelse (bh);
883 iput (dir);
884 oldinode->i_nlink++;
885 oldinode->i_ctime = CURRENT_TIME;
886 oldinode->i_dirt = 1;
887 iput (oldinode);
888 return 0;
889 }
890
891 static int subdir (struct inode * new_inode, struct inode * old_inode)
892 {
893 int ino;
894 int result;
895
896 new_inode->i_count++;
897 result = 0;
898 for (;;) {
899 if (new_inode == old_inode) {
900 result = 1;
901 break;
902 }
903 if (new_inode->i_dev != old_inode->i_dev)
904 break;
905 ino = new_inode->i_ino;
906 if (ext2_lookup (new_inode, "..", 2, &new_inode))
907 break;
908 if (new_inode->i_ino == ino)
909 break;
910 }
911 iput (new_inode);
912 return result;
913 }
914
915 #define PARENT_INO(buffer) \
916 ((struct ext2_dir_entry *) ((char *) buffer + \
917 ((struct ext2_dir_entry *) buffer)->rec_len))->inode
918
919 #define PARENT_NAME(buffer) \
920 ((struct ext2_dir_entry *) ((char *) buffer + \
921 ((struct ext2_dir_entry *) buffer)->rec_len))->name
922
923
924
925
926
927
928
929
930
931
932
933
934 static int do_ext2_rename (struct inode * old_dir, const char * old_name,
935 int old_len, struct inode * new_dir,
936 const char * new_name, int new_len)
937 {
938 struct inode * old_inode, * new_inode;
939 struct buffer_head * old_bh, * new_bh, * dir_bh;
940 struct ext2_dir_entry * old_de, * new_de;
941 int retval;
942
943 goto start_up;
944 try_again:
945 if (new_bh && new_de)
946 ext2_delete_entry(new_de, new_bh);
947 brelse (old_bh);
948 brelse (new_bh);
949 brelse (dir_bh);
950 iput (old_inode);
951 iput (new_inode);
952 current->counter = 0;
953 schedule ();
954 start_up:
955 old_inode = new_inode = NULL;
956 old_bh = new_bh = dir_bh = NULL;
957 new_de = NULL;
958 old_bh = ext2_find_entry (old_dir, old_name, old_len, &old_de);
959 retval = -ENOENT;
960 if (!old_bh)
961 goto end_rename;
962 old_inode = __iget (old_dir->i_sb, old_de->inode, 0);
963 if (!old_inode)
964 goto end_rename;
965 retval = -EPERM;
966 if ((old_dir->i_mode & S_ISVTX) &&
967 current->euid != old_inode->i_uid &&
968 current->euid != old_dir->i_uid && !suser())
969 goto end_rename;
970 new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de);
971 if (new_bh) {
972 new_inode = __iget (new_dir->i_sb, new_de->inode, 0);
973 if (!new_inode) {
974 brelse (new_bh);
975 new_bh = NULL;
976 }
977 }
978 if (new_inode == old_inode) {
979 retval = 0;
980 goto end_rename;
981 }
982 if (new_inode && S_ISDIR(new_inode->i_mode)) {
983 retval = -EISDIR;
984 if (!S_ISDIR(old_inode->i_mode))
985 goto end_rename;
986 retval = -EINVAL;
987 if (subdir (new_dir, old_inode))
988 goto end_rename;
989 retval = -ENOTEMPTY;
990 if (!empty_dir (new_inode))
991 goto end_rename;
992 retval = -EBUSY;
993 if (new_inode->i_count > 1)
994 goto end_rename;
995 }
996 retval = -EPERM;
997 if (new_inode && (new_dir->i_mode & S_ISVTX) &&
998 current->euid != new_inode->i_uid &&
999 current->euid != new_dir->i_uid && !suser())
1000 goto end_rename;
1001 if (S_ISDIR(old_inode->i_mode)) {
1002 retval = -ENOTDIR;
1003 if (new_inode && !S_ISDIR(new_inode->i_mode))
1004 goto end_rename;
1005 retval = -EINVAL;
1006 if (subdir (new_dir, old_inode))
1007 goto end_rename;
1008 dir_bh = ext2_bread (old_inode, 0, 0, &retval);
1009 if (!dir_bh)
1010 goto end_rename;
1011 if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
1012 goto end_rename;
1013 retval = -EMLINK;
1014 if (!new_inode && new_dir->i_nlink >= EXT2_LINK_MAX)
1015 goto end_rename;
1016 }
1017 if (!new_bh)
1018 new_bh = ext2_add_entry (new_dir, new_name, new_len, &new_de,
1019 &retval);
1020 if (!new_bh)
1021 goto end_rename;
1022
1023
1024
1025 if (new_inode && (new_de->inode != new_inode->i_ino))
1026 goto try_again;
1027 if (new_de->inode && !new_inode)
1028 goto try_again;
1029 if (old_de->inode != old_inode->i_ino)
1030 goto try_again;
1031
1032
1033
1034 new_de->inode = old_inode->i_ino;
1035 #ifndef DONT_USE_DCACHE
1036 ext2_dcache_remove (old_dir->i_dev, old_dir->i_ino, old_de->name,
1037 old_de->name_len);
1038 ext2_dcache_add (new_dir->i_dev, new_dir->i_ino, new_de->name,
1039 new_de->name_len, new_de->inode);
1040 #endif
1041 retval = ext2_delete_entry (old_de, old_bh);
1042 if (retval == -ENOENT)
1043 goto try_again;
1044 if (retval)
1045 goto end_rename;
1046 new_dir->i_version++;
1047 old_dir->i_version++;
1048 if (new_inode) {
1049 new_inode->i_nlink--;
1050 new_inode->i_ctime = CURRENT_TIME;
1051 new_inode->i_dirt = 1;
1052 }
1053 old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
1054 old_dir->i_dirt = 1;
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 mark_buffer_dirty(old_bh, 1);
1069 if (IS_SYNC(old_dir)) {
1070 ll_rw_block (WRITE, 1, &old_bh);
1071 wait_on_buffer (old_bh);
1072 }
1073 mark_buffer_dirty(new_bh, 1);
1074 if (IS_SYNC(new_dir)) {
1075 ll_rw_block (WRITE, 1, &new_bh);
1076 wait_on_buffer (new_bh);
1077 }
1078 retval = 0;
1079 end_rename:
1080 brelse (dir_bh);
1081 brelse (old_bh);
1082 brelse (new_bh);
1083 iput (old_inode);
1084 iput (new_inode);
1085 iput (old_dir);
1086 iput (new_dir);
1087 return retval;
1088 }
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103 int ext2_rename (struct inode * old_dir, const char * old_name, int old_len,
1104 struct inode * new_dir, const char * new_name, int new_len)
1105 {
1106 int result;
1107
1108 while (old_dir->i_sb->u.ext2_sb.s_rename_lock)
1109 sleep_on (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1110 old_dir->i_sb->u.ext2_sb.s_rename_lock = 1;
1111 result = do_ext2_rename (old_dir, old_name, old_len, new_dir,
1112 new_name, new_len);
1113 old_dir->i_sb->u.ext2_sb.s_rename_lock = 0;
1114 wake_up (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1115 return result;
1116 }