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 && !buffer_uptodate(bh))
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 (!buffer_uptodate(bh)) {
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 && !buffer_uptodate(bh))
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, &err);
379 if (!inode) {
380 iput (dir);
381 return err;
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, &err);
425 if (!inode) {
426 iput (dir);
427 return err;
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 = to_kdev_t(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, &err);
492 if (!inode) {
493 iput (dir);
494 return err;
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_sb->dq_op)
626 inode->i_sb->dq_op->initialize (inode, -1);
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) && !fsuser() &&
637 current->fsuid != inode->i_uid &&
638 current->fsuid != 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 = ++event;
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 if (inode->i_nlink != 2)
674 ext2_warning (inode->i_sb, "ext2_rmdir",
675 "empty directory has nlink!=2 (%d)",
676 inode->i_nlink);
677 inode->i_version = ++event;
678 inode->i_nlink = 0;
679 inode->i_dirt = 1;
680 dir->i_nlink--;
681 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
682 dir->i_dirt = 1;
683 end_rmdir:
684 iput (dir);
685 iput (inode);
686 brelse (bh);
687 return retval;
688 }
689
690 int ext2_unlink (struct inode * dir, const char * name, int len)
691 {
692 int retval;
693 struct inode * inode;
694 struct buffer_head * bh;
695 struct ext2_dir_entry * de;
696
697 repeat:
698 if (!dir)
699 return -ENOENT;
700 retval = -ENOENT;
701 inode = NULL;
702 bh = ext2_find_entry (dir, name, len, &de);
703 if (!bh)
704 goto end_unlink;
705 if (!(inode = iget (dir->i_sb, de->inode)))
706 goto end_unlink;
707 if (inode->i_sb->dq_op)
708 inode->i_sb->dq_op->initialize (inode, -1);
709 retval = -EPERM;
710 if (S_ISDIR(inode->i_mode))
711 goto end_unlink;
712 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
713 goto end_unlink;
714 if (de->inode != inode->i_ino) {
715 iput(inode);
716 brelse(bh);
717 current->counter = 0;
718 schedule();
719 goto repeat;
720 }
721 if ((dir->i_mode & S_ISVTX) && !fsuser() &&
722 current->fsuid != inode->i_uid &&
723 current->fsuid != dir->i_uid)
724 goto end_unlink;
725 if (!inode->i_nlink) {
726 ext2_warning (inode->i_sb, "ext2_unlink",
727 "Deleting nonexistent file (%lu), %d",
728 inode->i_ino, inode->i_nlink);
729 inode->i_nlink = 1;
730 }
731 retval = ext2_delete_entry (de, bh);
732 if (retval)
733 goto end_unlink;
734 dir->i_version = ++event;
735 mark_buffer_dirty(bh, 1);
736 if (IS_SYNC(dir)) {
737 ll_rw_block (WRITE, 1, &bh);
738 wait_on_buffer (bh);
739 }
740 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
741 dir->i_dirt = 1;
742 inode->i_nlink--;
743 inode->i_dirt = 1;
744 inode->i_ctime = dir->i_ctime;
745 retval = 0;
746 end_unlink:
747 brelse (bh);
748 iput (inode);
749 iput (dir);
750 return retval;
751 }
752
753 int ext2_symlink (struct inode * dir, const char * name, int len,
754 const char * symname)
755 {
756 struct ext2_dir_entry * de;
757 struct inode * inode = NULL;
758 struct buffer_head * bh = NULL, * name_block = NULL;
759 char * link;
760 int i, err;
761 int l;
762 char c;
763
764 if (!(inode = ext2_new_inode (dir, S_IFLNK, &err))) {
765 iput (dir);
766 return err;
767 }
768 inode->i_mode = S_IFLNK | S_IRWXUGO;
769 inode->i_op = &ext2_symlink_inode_operations;
770 for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
771 symname [l]; l++)
772 ;
773 if (l >= sizeof (inode->u.ext2_i.i_data)) {
774
775 ext2_debug ("l=%d, normal symlink\n", l);
776
777 name_block = ext2_bread (inode, 0, 1, &err);
778 if (!name_block) {
779 iput (dir);
780 inode->i_nlink--;
781 inode->i_dirt = 1;
782 iput (inode);
783 return err;
784 }
785 link = name_block->b_data;
786 } else {
787 link = (char *) inode->u.ext2_i.i_data;
788
789 ext2_debug ("l=%d, fast symlink\n", l);
790
791 }
792 i = 0;
793 while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
794 link[i++] = c;
795 link[i] = 0;
796 if (name_block) {
797 mark_buffer_dirty(name_block, 1);
798 brelse (name_block);
799 }
800 inode->i_size = i;
801 inode->i_dirt = 1;
802
803 bh = ext2_find_entry (dir, name, len, &de);
804 if (bh) {
805 inode->i_nlink--;
806 inode->i_dirt = 1;
807 iput (inode);
808 brelse (bh);
809 iput (dir);
810 return -EEXIST;
811 }
812 bh = ext2_add_entry (dir, name, len, &de, &err);
813 if (!bh) {
814 inode->i_nlink--;
815 inode->i_dirt = 1;
816 iput (inode);
817 iput (dir);
818 return err;
819 }
820 de->inode = inode->i_ino;
821 dir->i_version = ++event;
822 dcache_add(dir, de->name, de->name_len, de->inode);
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 (IS_APPEND(oldinode) || IS_IMMUTABLE(oldinode)) {
847 iput (oldinode);
848 iput (dir);
849 return -EPERM;
850 }
851 if (oldinode->i_nlink >= EXT2_LINK_MAX) {
852 iput (oldinode);
853 iput (dir);
854 return -EMLINK;
855 }
856 bh = ext2_find_entry (dir, name, len, &de);
857 if (bh) {
858 brelse (bh);
859 iput (dir);
860 iput (oldinode);
861 return -EEXIST;
862 }
863 bh = ext2_add_entry (dir, name, len, &de, &err);
864 if (!bh) {
865 iput (dir);
866 iput (oldinode);
867 return err;
868 }
869 de->inode = oldinode->i_ino;
870 dir->i_version = ++event;
871 dcache_add(dir, de->name, de->name_len, de->inode);
872 mark_buffer_dirty(bh, 1);
873 if (IS_SYNC(dir)) {
874 ll_rw_block (WRITE, 1, &bh);
875 wait_on_buffer (bh);
876 }
877 brelse (bh);
878 iput (dir);
879 oldinode->i_nlink++;
880 oldinode->i_ctime = CURRENT_TIME;
881 oldinode->i_dirt = 1;
882 iput (oldinode);
883 return 0;
884 }
885
886 static int subdir (struct inode * new_inode, struct inode * old_inode)
887 {
888 int ino;
889 int result;
890
891 new_inode->i_count++;
892 result = 0;
893 for (;;) {
894 if (new_inode == old_inode) {
895 result = 1;
896 break;
897 }
898 if (new_inode->i_dev != old_inode->i_dev)
899 break;
900 ino = new_inode->i_ino;
901 if (ext2_lookup (new_inode, "..", 2, &new_inode))
902 break;
903 if (new_inode->i_ino == ino)
904 break;
905 }
906 iput (new_inode);
907 return result;
908 }
909
910 #define PARENT_INO(buffer) \
911 ((struct ext2_dir_entry *) ((char *) buffer + \
912 ((struct ext2_dir_entry *) buffer)->rec_len))->inode
913
914 #define PARENT_NAME(buffer) \
915 ((struct ext2_dir_entry *) ((char *) buffer + \
916 ((struct ext2_dir_entry *) buffer)->rec_len))->name
917
918
919
920
921
922
923
924
925
926
927
928
929 static int do_ext2_rename (struct inode * old_dir, const char * old_name,
930 int old_len, struct inode * new_dir,
931 const char * new_name, int new_len)
932 {
933 struct inode * old_inode, * new_inode;
934 struct buffer_head * old_bh, * new_bh, * dir_bh;
935 struct ext2_dir_entry * old_de, * new_de;
936 int retval;
937
938 goto start_up;
939 try_again:
940 if (new_bh && new_de) {
941 ext2_delete_entry(new_de, new_bh);
942 new_dir->i_version = ++event;
943 }
944 brelse (old_bh);
945 brelse (new_bh);
946 brelse (dir_bh);
947 iput (old_inode);
948 iput (new_inode);
949 current->counter = 0;
950 schedule ();
951 start_up:
952 old_inode = new_inode = NULL;
953 old_bh = new_bh = dir_bh = NULL;
954 new_de = NULL;
955 old_bh = ext2_find_entry (old_dir, old_name, old_len, &old_de);
956 retval = -ENOENT;
957 if (!old_bh)
958 goto end_rename;
959 old_inode = __iget (old_dir->i_sb, old_de->inode, 0);
960 if (!old_inode)
961 goto end_rename;
962 retval = -EPERM;
963 if ((old_dir->i_mode & S_ISVTX) &&
964 current->fsuid != old_inode->i_uid &&
965 current->fsuid != old_dir->i_uid && !fsuser())
966 goto end_rename;
967 if (IS_APPEND(old_inode) || IS_IMMUTABLE(old_inode))
968 goto end_rename;
969 new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de);
970 if (new_bh) {
971 new_inode = __iget (new_dir->i_sb, new_de->inode, 0);
972 if (!new_inode) {
973 brelse (new_bh);
974 new_bh = NULL;
975 } else {
976 if (new_inode->i_sb->dq_op)
977 new_inode->i_sb->dq_op->initialize (new_inode, -1);
978 }
979 }
980 if (new_inode == old_inode) {
981 retval = 0;
982 goto end_rename;
983 }
984 if (new_inode && S_ISDIR(new_inode->i_mode)) {
985 retval = -EISDIR;
986 if (!S_ISDIR(old_inode->i_mode))
987 goto end_rename;
988 retval = -EINVAL;
989 if (subdir (new_dir, old_inode))
990 goto end_rename;
991 retval = -ENOTEMPTY;
992 if (!empty_dir (new_inode))
993 goto end_rename;
994 retval = -EBUSY;
995 if (new_inode->i_count > 1)
996 goto end_rename;
997 }
998 retval = -EPERM;
999 if (new_inode && (new_dir->i_mode & S_ISVTX) &&
1000 current->fsuid != new_inode->i_uid &&
1001 current->fsuid != new_dir->i_uid && !fsuser())
1002 goto end_rename;
1003 if (S_ISDIR(old_inode->i_mode)) {
1004 retval = -ENOTDIR;
1005 if (new_inode && !S_ISDIR(new_inode->i_mode))
1006 goto end_rename;
1007 retval = -EINVAL;
1008 if (subdir (new_dir, old_inode))
1009 goto end_rename;
1010 dir_bh = ext2_bread (old_inode, 0, 0, &retval);
1011 if (!dir_bh)
1012 goto end_rename;
1013 if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
1014 goto end_rename;
1015 retval = -EMLINK;
1016 if (!new_inode && new_dir->i_nlink >= EXT2_LINK_MAX)
1017 goto end_rename;
1018 }
1019 if (!new_bh)
1020 new_bh = ext2_add_entry (new_dir, new_name, new_len, &new_de,
1021 &retval);
1022 if (!new_bh)
1023 goto end_rename;
1024 new_dir->i_version = ++event;
1025
1026
1027
1028 if (new_inode && (new_de->inode != new_inode->i_ino))
1029 goto try_again;
1030 if (new_de->inode && !new_inode)
1031 goto try_again;
1032 if (old_de->inode != old_inode->i_ino)
1033 goto try_again;
1034
1035
1036
1037 new_de->inode = old_inode->i_ino;
1038 dcache_add(new_dir, new_de->name, new_de->name_len, new_de->inode);
1039 retval = ext2_delete_entry (old_de, old_bh);
1040 if (retval == -ENOENT)
1041 goto try_again;
1042 if (retval)
1043 goto end_rename;
1044 old_dir->i_version = ++event;
1045 if (new_inode) {
1046 new_inode->i_nlink--;
1047 new_inode->i_ctime = CURRENT_TIME;
1048 new_inode->i_dirt = 1;
1049 }
1050 old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
1051 old_dir->i_dirt = 1;
1052 if (dir_bh) {
1053 PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
1054 dcache_add(old_inode, "..", 2, new_dir->i_ino);
1055 mark_buffer_dirty(dir_bh, 1);
1056 old_dir->i_nlink--;
1057 old_dir->i_dirt = 1;
1058 if (new_inode) {
1059 new_inode->i_nlink--;
1060 new_inode->i_dirt = 1;
1061 } else {
1062 new_dir->i_nlink++;
1063 new_dir->i_dirt = 1;
1064 }
1065 }
1066 mark_buffer_dirty(old_bh, 1);
1067 if (IS_SYNC(old_dir)) {
1068 ll_rw_block (WRITE, 1, &old_bh);
1069 wait_on_buffer (old_bh);
1070 }
1071 mark_buffer_dirty(new_bh, 1);
1072 if (IS_SYNC(new_dir)) {
1073 ll_rw_block (WRITE, 1, &new_bh);
1074 wait_on_buffer (new_bh);
1075 }
1076 retval = 0;
1077 end_rename:
1078 brelse (dir_bh);
1079 brelse (old_bh);
1080 brelse (new_bh);
1081 iput (old_inode);
1082 iput (new_inode);
1083 iput (old_dir);
1084 iput (new_dir);
1085 return retval;
1086 }
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101 int ext2_rename (struct inode * old_dir, const char * old_name, int old_len,
1102 struct inode * new_dir, const char * new_name, int new_len)
1103 {
1104 int result;
1105
1106 while (old_dir->i_sb->u.ext2_sb.s_rename_lock)
1107 sleep_on (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1108 old_dir->i_sb->u.ext2_sb.s_rename_lock = 1;
1109 result = do_ext2_rename (old_dir, old_name, old_len, new_dir,
1110 new_name, new_len);
1111 old_dir->i_sb->u.ext2_sb.s_rename_lock = 0;
1112 wake_up (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1113 return result;
1114 }