This source file includes following definitions.
- xiafs_match
- xiafs_find_entry
- xiafs_lookup
- xiafs_add_entry
- xiafs_create
- xiafs_mknod
- xiafs_mkdir
- empty_dir
- xiafs_rm_entry
- xiafs_rmdir
- xiafs_unlink
- xiafs_symlink
- xiafs_link
- subdir
- do_xiafs_rename
- xiafs_rename
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/sched.h>
13 #include <linux/xia_fs.h>
14 #include <linux/kernel.h>
15 #include <linux/string.h>
16 #include <linux/stat.h>
17 #include <linux/fcntl.h>
18 #include <linux/errno.h>
19 #include <asm/segment.h>
20
21 #include "xiafs_mac.h"
22
23 #define RNDUP4(x) ((3+(u_long)(x)) & ~3)
24
25
26
27
28
29
30
31 static int xiafs_match(int len, const char * name, struct xiafs_direct * dep)
32 {
33 int i;
34
35 if (!dep || !dep->d_ino || len > _XIAFS_NAME_LEN)
36 return 0;
37
38 if (!len && (dep->d_name[0]=='.') && (dep->d_name[1]=='\0'))
39 return 1;
40 if (len < _XIAFS_NAME_LEN && dep->d_name[len])
41 return 0;
42 for (i=0; i < len; i++)
43 if (*name++ != dep->d_name[i])
44 break;
45 return (i==len) ? 1 : 0;
46 }
47
48
49
50
51
52
53
54
55
56 static struct buffer_head *
57 xiafs_find_entry(struct inode * inode, const char * name, int namelen,
58 struct xiafs_direct ** res_dir, struct xiafs_direct ** res_pre)
59 {
60 int i, zones, pos;
61 struct buffer_head * bh;
62 struct xiafs_direct * dep, * dep_pre;
63
64 *res_dir = NULL;
65 if (!inode)
66 return NULL;
67 if (namelen > _XIAFS_NAME_LEN)
68 return NULL;
69
70 if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb) - 1)) {
71 printk("XIA-FS: bad dir size (%s %d)\n", WHERE_ERR);
72 return NULL;
73 }
74 zones=inode->i_size >> XIAFS_ZSIZE_BITS(inode->i_sb);
75 for (i=0; i < zones; i++ ) {
76 bh = xiafs_bread(inode, i, 0);
77 if (!bh)
78 continue;
79 dep_pre=dep=(struct xiafs_direct *)bh->b_data;
80 if (!i && (dep->d_rec_len != 12 || !dep->d_ino ||
81 dep->d_name_len != 1 || strcmp(dep->d_name, "."))) {
82 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
83 brelse(bh);
84 return NULL;
85 }
86 pos = 0;
87 while ( pos < XIAFS_ZSIZE(inode->i_sb) ) {
88 if (dep->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes ||
89 dep->d_rec_len < 12 ||
90 dep->d_rec_len+(char *)dep > bh->b_data+XIAFS_ZSIZE(inode->i_sb) ||
91 dep->d_name_len + 8 > dep->d_rec_len || dep->d_name_len <= 0 ||
92 dep->d_name[dep->d_name_len] ) {
93 brelse(bh);
94 return NULL;
95 }
96 if (xiafs_match(namelen, name, dep)) {
97 *res_dir=dep;
98 if (res_pre)
99 *res_pre=dep_pre;
100 return bh;
101 }
102 pos += dep->d_rec_len;
103 dep_pre=dep;
104 dep=(struct xiafs_direct *)(bh->b_data + pos);
105 }
106 brelse(bh);
107 if (pos > XIAFS_ZSIZE(inode->i_sb)) {
108 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
109 return NULL;
110 }
111 }
112 return NULL;
113 }
114
115 int xiafs_lookup(struct inode * dir, const char * name, int len,
116 struct inode ** result)
117 {
118 int ino;
119 struct xiafs_direct * dep;
120 struct buffer_head * bh;
121
122 *result = NULL;
123 if (!dir)
124 return -ENOENT;
125 if (!S_ISDIR(dir->i_mode)) {
126 iput(dir);
127 return -ENOENT;
128 }
129 if (!(bh = xiafs_find_entry(dir, name, len, &dep, NULL))) {
130 iput(dir);
131 return -ENOENT;
132 }
133 ino = dep->d_ino;
134 brelse(bh);
135 if (!(*result = iget(dir->i_sb, ino))) {
136 iput(dir);
137 return -EACCES;
138 }
139 iput(dir);
140 return 0;
141 }
142
143
144
145
146
147
148
149
150
151
152
153 static struct buffer_head * xiafs_add_entry(struct inode * dir,
154 const char * name, int namelen, struct xiafs_direct ** res_dir,
155 struct xiafs_direct ** res_pre)
156 {
157 int i, pos, offset;
158 struct buffer_head * bh;
159 struct xiafs_direct * de, * de_pre;
160
161 *res_dir = NULL;
162 if (!dir || !namelen || namelen > _XIAFS_NAME_LEN)
163 return NULL;
164
165 if (dir->i_size & (XIAFS_ZSIZE(dir->i_sb) - 1)) {
166 printk("XIA-FS: bad dir size (%s %d)\n", WHERE_ERR);
167 return NULL;
168 }
169 pos=0;
170 for ( ; ; ) {
171 bh = xiafs_bread(dir, pos >> XIAFS_ZSIZE_BITS(dir->i_sb), pos ? 1:0);
172 if (!bh)
173 return NULL;
174 de_pre=de=(struct xiafs_direct *)bh->b_data;
175 if (!pos) {
176 if (de->d_rec_len != 12 || !de->d_ino || de->d_name_len != 1 ||
177 strcmp(de->d_name, ".")) {
178 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
179 brelse(bh);
180 return NULL;
181 }
182 offset = 12;
183 de_pre=de=(struct xiafs_direct *)(bh->b_data+12);
184 } else
185 offset = 0;
186 while (offset < XIAFS_ZSIZE(dir->i_sb)) {
187 if (pos >= dir->i_size) {
188 de->d_ino=0;
189 de->d_name_len=0;
190 de->d_name[0]=0;
191 de->d_rec_len=XIAFS_ZSIZE(dir->i_sb);
192 dir->i_size += XIAFS_ZSIZE(dir->i_sb);
193 dir->i_dirt = 1;
194 } else {
195 if (de->d_ino > dir->i_sb->u.xiafs_sb.s_ninodes ||
196 de->d_rec_len < 12 ||
197 (char *)de+de->d_rec_len > bh->b_data+XIAFS_ZSIZE(dir->i_sb) ||
198 de->d_name_len + 8 > de->d_rec_len ||
199 de->d_name[de->d_name_len]) {
200 printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR);
201 brelse(bh);
202 return NULL;
203 }
204 if (de->d_ino &&
205 RNDUP4(de->d_name_len)+RNDUP4(namelen)+16<=de->d_rec_len) {
206 i=RNDUP4(de->d_name_len)+8;
207 de_pre=de;
208 de=(struct xiafs_direct *)(i+(u_char *)de_pre);
209 de->d_ino=0;
210 de->d_rec_len=de_pre->d_rec_len-i;
211 de_pre->d_rec_len=i;
212 }
213 }
214 if (!de->d_ino && RNDUP4(namelen)+8 <= de->d_rec_len) {
215 dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
216 dir->i_dirt = 1;
217 memcpy(de->d_name, name, namelen);
218 de->d_name[namelen]=0;
219 de->d_name_len=namelen;
220 bh->b_dirt = 1;
221 *res_dir = de;
222 if (res_pre)
223 *res_pre = de_pre;
224 return bh;
225 }
226 offset+=de->d_rec_len;
227 de_pre=de;
228 de=(struct xiafs_direct *)(bh->b_data+offset);
229 }
230 brelse(bh);
231 if (offset > XIAFS_ZSIZE(dir->i_sb)) {
232 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
233 return NULL;
234 }
235 pos+=XIAFS_ZSIZE(dir->i_sb);
236 }
237 return NULL;
238 }
239
240 int xiafs_create(struct inode * dir, const char * name, int len, int mode,
241 struct inode ** result)
242 {
243 struct inode * inode;
244 struct buffer_head * bh;
245 struct xiafs_direct * de;
246
247 *result = NULL;
248 if (!dir)
249 return -ENOENT;
250 inode = xiafs_new_inode(dir);
251 if (!inode) {
252 iput(dir);
253 return -ENOSPC;
254 }
255 inode->i_op = &xiafs_file_inode_operations;
256 inode->i_mode = mode;
257 inode->i_dirt = 1;
258 bh = xiafs_add_entry(dir, name, len, &de, NULL);
259 if (!bh) {
260 inode->i_nlink--;
261 inode->i_dirt = 1;
262 iput(inode);
263 iput(dir);
264 return -ENOSPC;
265 }
266 de->d_ino = inode->i_ino;
267 bh->b_dirt = 1;
268 brelse(bh);
269 iput(dir);
270 *result = inode;
271 return 0;
272 }
273
274 int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev)
275 {
276 struct inode * inode;
277 struct buffer_head * bh;
278 struct xiafs_direct * de;
279
280 if (!dir)
281 return -ENOENT;
282 bh = xiafs_find_entry(dir,name,len,&de, NULL);
283 if (bh) {
284 brelse(bh);
285 iput(dir);
286 return -EEXIST;
287 }
288 inode = xiafs_new_inode(dir);
289 if (!inode) {
290 iput(dir);
291 return -ENOSPC;
292 }
293 inode->i_uid = current->euid;
294 inode->i_mode = mode;
295 inode->i_op = NULL;
296 if (S_ISREG(inode->i_mode))
297 inode->i_op = &xiafs_file_inode_operations;
298 else if (S_ISDIR(inode->i_mode)) {
299 inode->i_op = &xiafs_dir_inode_operations;
300 if (dir->i_mode & S_ISGID)
301 inode->i_mode |= S_ISGID;
302 }
303 else if (S_ISLNK(inode->i_mode))
304 inode->i_op = &xiafs_symlink_inode_operations;
305 else if (S_ISCHR(inode->i_mode))
306 inode->i_op = &chrdev_inode_operations;
307 else if (S_ISBLK(inode->i_mode))
308 inode->i_op = &blkdev_inode_operations;
309 else if (S_ISFIFO(inode->i_mode)) {
310 inode->i_op = &fifo_inode_operations;
311 inode->i_pipe = 1;
312 PIPE_BASE(*inode) = NULL;
313 PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
314 PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
315 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
316 }
317 if (S_ISBLK(mode) || S_ISCHR(mode))
318 inode->i_rdev = rdev;
319 inode->i_atime = inode->i_ctime = inode->i_atime = CURRENT_TIME;
320 inode->i_dirt = 1;
321 bh = xiafs_add_entry(dir, name, len, &de, NULL);
322 if (!bh) {
323 inode->i_nlink--;
324 inode->i_dirt = 1;
325 iput(inode);
326 iput(dir);
327 return -ENOSPC;
328 }
329 de->d_ino = inode->i_ino;
330 bh->b_dirt = 1;
331 brelse(bh);
332 iput(dir);
333 iput(inode);
334 return 0;
335 }
336
337 int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
338 {
339 struct inode * inode;
340 struct buffer_head * bh, *dir_block;
341 struct xiafs_direct * de;
342
343 bh = xiafs_find_entry(dir,name,len,&de, NULL);
344 if (bh) {
345 brelse(bh);
346 iput(dir);
347 return -EEXIST;
348 }
349 if (dir->i_nlink > 64000) {
350 iput(dir);
351 return -EMLINK;
352 }
353 inode = xiafs_new_inode(dir);
354 if (!inode) {
355 iput(dir);
356 return -ENOSPC;
357 }
358 inode->i_op = &xiafs_dir_inode_operations;
359 inode->i_size = XIAFS_ZSIZE(dir->i_sb);
360 inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
361 dir_block = xiafs_bread(inode,0,1);
362 if (!dir_block) {
363 iput(dir);
364 inode->i_nlink--;
365 inode->i_dirt = 1;
366 iput(inode);
367 return -ENOSPC;
368 }
369 de = (struct xiafs_direct *) dir_block->b_data;
370 de->d_ino=inode->i_ino;
371 strcpy(de->d_name,".");
372 de->d_name_len=1;
373 de->d_rec_len=12;
374 de =(struct xiafs_direct *)(12 + dir_block->b_data);
375 de->d_ino = dir->i_ino;
376 strcpy(de->d_name,"..");
377 de->d_name_len=2;
378 de->d_rec_len=XIAFS_ZSIZE(dir->i_sb)-12;
379 inode->i_nlink = 2;
380 dir_block->b_dirt = 1;
381 brelse(dir_block);
382 inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
383 if (dir->i_mode & S_ISGID)
384 inode->i_mode |= S_ISGID;
385 inode->i_dirt = 1;
386 bh = xiafs_add_entry(dir, name, len, &de, NULL);
387 if (!bh) {
388 iput(dir);
389 inode->i_nlink=0;
390 iput(inode);
391 return -ENOSPC;
392 }
393 de->d_ino = inode->i_ino;
394 bh->b_dirt = 1;
395 dir->i_nlink++;
396 dir->i_dirt = 1;
397 iput(dir);
398 iput(inode);
399 brelse(bh);
400 return 0;
401 }
402
403
404
405
406 static int empty_dir(struct inode * inode)
407 {
408 int i, zones, offset;
409 struct buffer_head * bh;
410 struct xiafs_direct * de;
411
412 if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb)-1) ) {
413 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
414 return 1;
415 }
416
417 zones=inode->i_size >> XIAFS_ZSIZE_BITS(inode->i_sb);
418 for (i=0; i < zones; i++) {
419 bh = xiafs_bread(inode, i, 0);
420 if (!i) {
421 if (!bh) {
422 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
423 return 1;
424 }
425 de=(struct xiafs_direct *)bh->b_data;
426 if (de->d_ino != inode->i_ino || strcmp(".", de->d_name) ||
427 de->d_rec_len != 12 ) {
428 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
429 brelse(bh);
430 return 1;
431 }
432 de=(struct xiafs_direct *)(12 + bh->b_data);
433 if (!de->d_ino || strcmp("..", de->d_name)) {
434 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
435 brelse(bh);
436 return 1;
437 }
438 offset=de->d_rec_len+12;
439 }
440 else
441 offset = 0;
442 if (!bh)
443 continue;
444 while (offset < XIAFS_ZSIZE(inode->i_sb)) {
445 de=(struct xiafs_direct *)(bh->b_data+offset);
446 if (de->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes ||
447 de->d_rec_len < 12 ||
448 (char *)de+de->d_rec_len > bh->b_data+XIAFS_ZSIZE(inode->i_sb) ||
449 de->d_name_len + 8 > de->d_rec_len ||
450 de->d_name[de->d_name_len]) {
451 printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
452 brelse(bh);
453 return 1;
454 }
455 if (de->d_ino) {
456 brelse(bh);
457 return 0;
458 }
459 offset+=de->d_rec_len;
460 }
461 brelse(bh);
462 }
463 return 1;
464 }
465
466 static void xiafs_rm_entry(struct xiafs_direct *de, struct xiafs_direct * de_pre)
467 {
468 if (de==de_pre) {
469 de->d_ino=0;
470 return;
471 }
472 while (de_pre->d_rec_len+(u_char *)de_pre < (u_char *)de) {
473 if (de_pre->d_rec_len < 12) {
474 printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR);
475 return;
476 }
477 de_pre=(struct xiafs_direct *)(de_pre->d_rec_len+(u_char *)de_pre);
478 }
479 if (de_pre->d_rec_len+(u_char *)de_pre > (u_char *)de) {
480 printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR);
481 return;
482 }
483 de_pre->d_rec_len+=de->d_rec_len;
484 }
485
486 int xiafs_rmdir(struct inode * dir, const char * name, int len)
487 {
488 int retval;
489 struct inode * inode;
490 struct buffer_head * bh;
491 struct xiafs_direct * de, * de_pre;
492
493 inode = NULL;
494 bh = xiafs_find_entry(dir, name, len, &de, &de_pre);
495 retval = -ENOENT;
496 if (!bh)
497 goto end_rmdir;
498 retval = -EPERM;
499 if (!(inode = iget(dir->i_sb, de->d_ino)))
500 goto end_rmdir;
501 if ((dir->i_mode & S_ISVTX) && current->euid &&
502 inode->i_uid != current->euid)
503 goto end_rmdir;
504 if (inode->i_dev != dir->i_dev)
505 goto end_rmdir;
506 if (inode == dir)
507 goto end_rmdir;
508 if (!S_ISDIR(inode->i_mode)) {
509 retval = -ENOTDIR;
510 goto end_rmdir;
511 }
512 if (!empty_dir(inode)) {
513 retval = -ENOTEMPTY;
514 goto end_rmdir;
515 }
516 if (inode->i_count > 1) {
517 retval = -EBUSY;
518 goto end_rmdir;
519 }
520 if (inode->i_nlink != 2)
521 printk("XIA-FS: empty directory has nlink!=2 (%s %d)\n", WHERE_ERR);
522 xiafs_rm_entry(de, de_pre);
523 bh->b_dirt = 1;
524 inode->i_nlink=0;
525 inode->i_dirt=1;
526 dir->i_nlink--;
527 dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
528 dir->i_dirt=1;
529 retval = 0;
530 end_rmdir:
531 iput(dir);
532 iput(inode);
533 brelse(bh);
534 return retval;
535 }
536
537 int xiafs_unlink(struct inode * dir, const char * name, int len)
538 {
539 int retval;
540 struct inode * inode;
541 struct buffer_head * bh;
542 struct xiafs_direct * de, * de_pre;
543
544 repeat:
545 retval = -ENOENT;
546 inode = NULL;
547 bh = xiafs_find_entry(dir, name, len, &de, &de_pre);
548 if (!bh)
549 goto end_unlink;
550 if (!(inode = iget(dir->i_sb, de->d_ino)))
551 goto end_unlink;
552 if (de->d_ino != inode->i_ino) {
553 iput(inode);
554 brelse(bh);
555 current->counter = 0;
556 schedule();
557 goto repeat;
558 }
559 retval = -EPERM;
560 if ((dir->i_mode & S_ISVTX) && !suser() &&
561 current->euid != inode->i_uid &&
562 current->euid != dir->i_uid)
563 goto end_unlink;
564 if (S_ISDIR(inode->i_mode))
565 goto end_unlink;
566 if (!inode->i_nlink) {
567 printk("XIA-FS: Deleting nonexistent file (%s %d)\n", WHERE_ERR);
568 inode->i_nlink=1;
569 }
570 xiafs_rm_entry(de, de_pre);
571 bh->b_dirt = 1;
572 dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
573 dir->i_dirt = 1;
574 inode->i_nlink--;
575 inode->i_dirt = 1;
576 retval = 0;
577 end_unlink:
578 brelse(bh);
579 iput(inode);
580 iput(dir);
581 return retval;
582 }
583
584 int xiafs_symlink(struct inode * dir, const char * name,
585 int len, const char * symname)
586 {
587 struct xiafs_direct * de;
588 struct inode * inode = NULL;
589 struct buffer_head * bh = NULL, * name_block = NULL;
590 int i;
591 char c;
592
593 bh = xiafs_find_entry(dir,name,len, &de, NULL);
594 if (bh) {
595 brelse(bh);
596 iput(dir);
597 return -EEXIST;
598 }
599 if (!(inode = xiafs_new_inode(dir))) {
600 iput(dir);
601 return -ENOSPC;
602 }
603 inode->i_mode = S_IFLNK | 0777;
604 inode->i_op = &xiafs_symlink_inode_operations;
605 name_block = xiafs_bread(inode,0,1);
606 if (!name_block) {
607 iput(dir);
608 inode->i_nlink--;
609 inode->i_dirt = 1;
610 iput(inode);
611 return -ENOSPC;
612 }
613 for (i = 0; i < BLOCK_SIZE-1 && (c=*symname++); i++)
614 name_block->b_data[i] = c;
615 name_block->b_data[i] = 0;
616 name_block->b_dirt = 1;
617 brelse(name_block);
618 inode->i_size = i;
619 inode->i_dirt = 1;
620 bh = xiafs_add_entry(dir, name, len, &de, NULL);
621 if (!bh) {
622 inode->i_nlink--;
623 inode->i_dirt = 1;
624 iput(inode);
625 iput(dir);
626 return -ENOSPC;
627 }
628 de->d_ino = inode->i_ino;
629 bh->b_dirt = 1;
630 brelse(bh);
631 iput(dir);
632 iput(inode);
633 return 0;
634 }
635
636 int xiafs_link(struct inode * oldinode, struct inode * dir,
637 const char * name, int len)
638 {
639 struct xiafs_direct * de;
640 struct buffer_head * bh;
641
642 if (S_ISDIR(oldinode->i_mode)) {
643 iput(oldinode);
644 iput(dir);
645 return -EPERM;
646 }
647 if (oldinode->i_nlink > 64000) {
648 iput(oldinode);
649 iput(dir);
650 return -EMLINK;
651 }
652 bh = xiafs_find_entry(dir, name, len, &de, NULL);
653 if (bh) {
654 brelse(bh);
655 iput(dir);
656 iput(oldinode);
657 return -EEXIST;
658 }
659 bh = xiafs_add_entry(dir, name, len, &de, NULL);
660 if (!bh) {
661 iput(dir);
662 iput(oldinode);
663 return -ENOSPC;
664 }
665 de->d_ino = oldinode->i_ino;
666 bh->b_dirt = 1;
667 brelse(bh);
668 iput(dir);
669 oldinode->i_nlink++;
670 oldinode->i_atime = oldinode->i_ctime = CURRENT_TIME;
671 oldinode->i_dirt = 1;
672 iput(oldinode);
673 return 0;
674 }
675
676 static int subdir(struct inode * new, struct inode * old)
677 {
678 int ino;
679 int result;
680
681 new->i_count++;
682 result = 0;
683 for (;;) {
684 if (new == old) {
685 result = 1;
686 break;
687 }
688 if (new->i_dev != old->i_dev)
689 break;
690 ino = new->i_ino;
691 if (xiafs_lookup(new,"..",2,&new))
692 break;
693 if (new->i_ino == ino)
694 break;
695 }
696 iput(new);
697 return result;
698 }
699
700 #define PARENT_INO(buffer) \
701 (((struct xiafs_direct *) ((u_char *)(buffer) + 12))->d_ino)
702
703
704
705
706
707
708
709
710
711
712
713 static int do_xiafs_rename(struct inode * old_dir, const char * old_name,
714 int old_len, struct inode * new_dir,
715 const char * new_name, int new_len)
716 {
717 struct inode * old_inode, * new_inode;
718 struct buffer_head * old_bh, * new_bh, * dir_bh;
719 struct xiafs_direct * old_de, * old_de_pre, * new_de, * new_de_pre;
720 int retval;
721
722 try_again:
723 old_inode = new_inode = NULL;
724 old_bh = new_bh = dir_bh = NULL;
725 old_bh = xiafs_find_entry(old_dir, old_name, old_len, &old_de, &old_de_pre);
726 retval = -ENOENT;
727 if (!old_bh)
728 goto end_rename;
729 old_inode = iget(old_dir->i_sb, old_de->d_ino);
730 if (!old_inode)
731 goto end_rename;
732 retval = -EPERM;
733 if ((old_dir->i_mode & S_ISVTX) &&
734 current->euid != old_inode->i_uid &&
735 current->euid != old_dir->i_uid && !suser())
736 goto end_rename;
737 new_bh = xiafs_find_entry(new_dir, new_name, new_len, &new_de, NULL);
738 if (new_bh) {
739 new_inode = iget(new_dir->i_sb, new_de->d_ino);
740 if (!new_inode) {
741 brelse(new_bh);
742 new_bh = NULL;
743 }
744 }
745 if (new_inode == old_inode) {
746 retval = 0;
747 goto end_rename;
748 }
749 if (new_inode && S_ISDIR(new_inode->i_mode)) {
750 retval = -EEXIST;
751 goto end_rename;
752 }
753 retval = -EPERM;
754 if (new_inode && (new_dir->i_mode & S_ISVTX) &&
755 current->euid != new_inode->i_uid &&
756 current->euid != new_dir->i_uid && !suser())
757 goto end_rename;
758 if (S_ISDIR(old_inode->i_mode)) {
759 retval = -EEXIST;
760 if (new_bh)
761 goto end_rename;
762 retval = -EACCES;
763 if (!permission(old_inode, MAY_WRITE))
764 goto end_rename;
765 retval = -EINVAL;
766 if (subdir(new_dir, old_inode))
767 goto end_rename;
768 retval = -EIO;
769 dir_bh = xiafs_bread(old_inode,0,0);
770 if (!dir_bh)
771 goto end_rename;
772 if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
773 goto end_rename;
774 retval = -EMLINK;
775 if (new_dir->i_nlink > 64000)
776 goto end_rename;
777 }
778 if (!new_bh)
779 new_bh = xiafs_add_entry(new_dir, new_name, new_len, &new_de, &new_de_pre);
780 retval = -ENOSPC;
781 if (!new_bh)
782 goto end_rename;
783
784 if ( (new_inode && (new_de->d_ino != new_inode->i_ino))
785 || (new_de->d_ino && !new_inode)
786 || (old_de->d_ino != old_inode->i_ino)) {
787 xiafs_rm_entry(new_de, new_de_pre);
788 brelse(old_bh);
789 brelse(new_bh);
790 brelse(dir_bh);
791 iput(old_inode);
792 iput(new_inode);
793 current->counter=0;
794 schedule();
795 goto try_again;
796 }
797 xiafs_rm_entry(old_de, old_de_pre);
798 new_de->d_ino = old_inode->i_ino;
799 if (new_inode) {
800 new_inode->i_nlink--;
801 new_inode->i_dirt = 1;
802 }
803 old_bh->b_dirt = 1;
804 new_bh->b_dirt = 1;
805 if (dir_bh) {
806 PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
807 dir_bh->b_dirt = 1;
808 old_dir->i_nlink--;
809 new_dir->i_nlink++;
810 old_dir->i_dirt = 1;
811 new_dir->i_dirt = 1;
812 }
813 retval = 0;
814 end_rename:
815 brelse(dir_bh);
816 brelse(old_bh);
817 brelse(new_bh);
818 iput(old_inode);
819 iput(new_inode);
820 iput(old_dir);
821 iput(new_dir);
822 return retval;
823 }
824
825
826
827
828
829
830
831
832
833
834 int xiafs_rename(struct inode * old_dir, const char * old_name, int old_len,
835 struct inode * new_dir, const char * new_name, int new_len)
836 {
837 static struct wait_queue * wait = NULL;
838 static int lock = 0;
839 int result;
840
841 while (lock)
842 sleep_on(&wait);
843 lock = 1;
844 result = do_xiafs_rename(old_dir, old_name, old_len,
845 new_dir, new_name, new_len);
846 lock = 0;
847 wake_up(&wait);
848 return result;
849 }
850
851
852
853
854