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