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