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