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