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 = to_kdev_t(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 %s\n",
426 kdevname(inode->i_dev));
427 return 1;
428 }
429
430 int minix_rmdir(struct inode * dir, const char * name, int len)
431 {
432 int retval;
433 struct inode * inode;
434 struct buffer_head * bh;
435 struct minix_dir_entry * de;
436
437 inode = NULL;
438 bh = minix_find_entry(dir,name,len,&de);
439 retval = -ENOENT;
440 if (!bh)
441 goto end_rmdir;
442 retval = -EPERM;
443 if (!(inode = iget(dir->i_sb, de->inode)))
444 goto end_rmdir;
445 if ((dir->i_mode & S_ISVTX) && !fsuser() &&
446 current->fsuid != inode->i_uid &&
447 current->fsuid != dir->i_uid)
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 dir->i_version = ++event;
473 mark_buffer_dirty(bh, 1);
474 inode->i_nlink=0;
475 inode->i_dirt=1;
476 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
477 dir->i_nlink--;
478 dir->i_dirt=1;
479 retval = 0;
480 end_rmdir:
481 iput(dir);
482 iput(inode);
483 brelse(bh);
484 return retval;
485 }
486
487 int minix_unlink(struct inode * dir, const char * name, int len)
488 {
489 int retval;
490 struct inode * inode;
491 struct buffer_head * bh;
492 struct minix_dir_entry * de;
493
494 repeat:
495 retval = -ENOENT;
496 inode = NULL;
497 bh = minix_find_entry(dir,name,len,&de);
498 if (!bh)
499 goto end_unlink;
500 if (!(inode = iget(dir->i_sb, de->inode)))
501 goto end_unlink;
502 retval = -EPERM;
503 if (S_ISDIR(inode->i_mode))
504 goto end_unlink;
505 if (de->inode != inode->i_ino) {
506 iput(inode);
507 brelse(bh);
508 current->counter = 0;
509 schedule();
510 goto repeat;
511 }
512 if ((dir->i_mode & S_ISVTX) && !fsuser() &&
513 current->fsuid != inode->i_uid &&
514 current->fsuid != dir->i_uid)
515 goto end_unlink;
516 if (de->inode != inode->i_ino) {
517 retval = -ENOENT;
518 goto end_unlink;
519 }
520 if (!inode->i_nlink) {
521 printk("Deleting nonexistent file (%s:%lu), %d\n",
522 kdevname(inode->i_dev),
523 inode->i_ino, inode->i_nlink);
524 inode->i_nlink=1;
525 }
526 de->inode = 0;
527 dir->i_version = ++event;
528 mark_buffer_dirty(bh, 1);
529 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
530 dir->i_dirt = 1;
531 inode->i_nlink--;
532 inode->i_ctime = dir->i_ctime;
533 inode->i_dirt = 1;
534 retval = 0;
535 end_unlink:
536 brelse(bh);
537 iput(inode);
538 iput(dir);
539 return retval;
540 }
541
542 int minix_symlink(struct inode * dir, const char * name, int len, const char * symname)
543 {
544 struct minix_dir_entry * de;
545 struct inode * inode = NULL;
546 struct buffer_head * bh = NULL, * name_block = NULL;
547 int i;
548 char c;
549
550 if (!(inode = minix_new_inode(dir))) {
551 iput(dir);
552 return -ENOSPC;
553 }
554 inode->i_mode = S_IFLNK | 0777;
555 inode->i_op = &minix_symlink_inode_operations;
556 name_block = minix_bread(inode,0,1);
557 if (!name_block) {
558 iput(dir);
559 inode->i_nlink--;
560 inode->i_dirt = 1;
561 iput(inode);
562 return -ENOSPC;
563 }
564 i = 0;
565 while (i < 1023 && (c=*(symname++)))
566 name_block->b_data[i++] = c;
567 name_block->b_data[i] = 0;
568 mark_buffer_dirty(name_block, 1);
569 brelse(name_block);
570 inode->i_size = i;
571 inode->i_dirt = 1;
572 bh = minix_find_entry(dir,name,len,&de);
573 if (bh) {
574 inode->i_nlink--;
575 inode->i_dirt = 1;
576 iput(inode);
577 brelse(bh);
578 iput(dir);
579 return -EEXIST;
580 }
581 i = minix_add_entry(dir, name, len, &bh, &de);
582 if (i) {
583 inode->i_nlink--;
584 inode->i_dirt = 1;
585 iput(inode);
586 iput(dir);
587 return i;
588 }
589 de->inode = inode->i_ino;
590 mark_buffer_dirty(bh, 1);
591 brelse(bh);
592 iput(dir);
593 iput(inode);
594 return 0;
595 }
596
597 int minix_link(struct inode * oldinode, struct inode * dir, const char * name, int len)
598 {
599 int error;
600 struct minix_dir_entry * de;
601 struct buffer_head * bh;
602
603 if (S_ISDIR(oldinode->i_mode)) {
604 iput(oldinode);
605 iput(dir);
606 return -EPERM;
607 }
608 if (oldinode->i_nlink >= MINIX_LINK_MAX) {
609 iput(oldinode);
610 iput(dir);
611 return -EMLINK;
612 }
613 bh = minix_find_entry(dir,name,len,&de);
614 if (bh) {
615 brelse(bh);
616 iput(dir);
617 iput(oldinode);
618 return -EEXIST;
619 }
620 error = minix_add_entry(dir, name, len, &bh, &de);
621 if (error) {
622 iput(dir);
623 iput(oldinode);
624 return error;
625 }
626 de->inode = oldinode->i_ino;
627 mark_buffer_dirty(bh, 1);
628 brelse(bh);
629 iput(dir);
630 oldinode->i_nlink++;
631 oldinode->i_ctime = CURRENT_TIME;
632 oldinode->i_dirt = 1;
633 iput(oldinode);
634 return 0;
635 }
636
637 static int subdir(struct inode * new_inode, struct inode * old_inode)
638 {
639 int ino;
640 int result;
641
642 new_inode->i_count++;
643 result = 0;
644 for (;;) {
645 if (new_inode == old_inode) {
646 result = 1;
647 break;
648 }
649 if (new_inode->i_dev != old_inode->i_dev)
650 break;
651 ino = new_inode->i_ino;
652 if (minix_lookup(new_inode,"..",2,&new_inode))
653 break;
654 if (new_inode->i_ino == ino)
655 break;
656 }
657 iput(new_inode);
658 return result;
659 }
660
661 #define PARENT_INO(buffer) \
662 (((struct minix_dir_entry *) ((buffer)+info->s_dirsize))->inode)
663
664
665
666
667
668
669
670
671
672
673
674 static int do_minix_rename(struct inode * old_dir, const char * old_name, int old_len,
675 struct inode * new_dir, const char * new_name, int new_len)
676 {
677 struct inode * old_inode, * new_inode;
678 struct buffer_head * old_bh, * new_bh, * dir_bh;
679 struct minix_dir_entry * old_de, * new_de;
680 struct minix_sb_info * info;
681 int retval;
682
683 info = &old_dir->i_sb->u.minix_sb;
684 goto start_up;
685 try_again:
686 brelse(old_bh);
687 brelse(new_bh);
688 brelse(dir_bh);
689 iput(old_inode);
690 iput(new_inode);
691 current->counter = 0;
692 schedule();
693 start_up:
694 old_inode = new_inode = NULL;
695 old_bh = new_bh = dir_bh = NULL;
696 old_bh = minix_find_entry(old_dir,old_name,old_len,&old_de);
697 retval = -ENOENT;
698 if (!old_bh)
699 goto end_rename;
700 old_inode = __iget(old_dir->i_sb, old_de->inode,0);
701 if (!old_inode)
702 goto end_rename;
703 retval = -EPERM;
704 if ((old_dir->i_mode & S_ISVTX) &&
705 current->fsuid != old_inode->i_uid &&
706 current->fsuid != old_dir->i_uid && !fsuser())
707 goto end_rename;
708 new_bh = minix_find_entry(new_dir,new_name,new_len,&new_de);
709 if (new_bh) {
710 new_inode = __iget(new_dir->i_sb, new_de->inode, 0);
711 if (!new_inode) {
712 brelse(new_bh);
713 new_bh = NULL;
714 }
715 }
716 if (new_inode == old_inode) {
717 retval = 0;
718 goto end_rename;
719 }
720 if (new_inode && S_ISDIR(new_inode->i_mode)) {
721 retval = -EISDIR;
722 if (!S_ISDIR(old_inode->i_mode))
723 goto end_rename;
724 retval = -EINVAL;
725 if (subdir(new_dir, old_inode))
726 goto end_rename;
727 retval = -ENOTEMPTY;
728 if (!empty_dir(new_inode))
729 goto end_rename;
730 retval = -EBUSY;
731 if (new_inode->i_count > 1)
732 goto end_rename;
733 }
734 retval = -EPERM;
735 if (new_inode && (new_dir->i_mode & S_ISVTX) &&
736 current->fsuid != new_inode->i_uid &&
737 current->fsuid != new_dir->i_uid && !fsuser())
738 goto end_rename;
739 if (S_ISDIR(old_inode->i_mode)) {
740 retval = -ENOTDIR;
741 if (new_inode && !S_ISDIR(new_inode->i_mode))
742 goto end_rename;
743 retval = -EINVAL;
744 if (subdir(new_dir, old_inode))
745 goto end_rename;
746 retval = -EIO;
747 dir_bh = minix_bread(old_inode,0,0);
748 if (!dir_bh)
749 goto end_rename;
750 if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
751 goto end_rename;
752 retval = -EMLINK;
753 if (!new_inode && new_dir->i_nlink >= MINIX_LINK_MAX)
754 goto end_rename;
755 }
756 if (!new_bh) {
757 retval = minix_add_entry(new_dir,new_name,new_len,&new_bh,&new_de);
758 if (retval)
759 goto end_rename;
760 }
761
762 if (new_inode && (new_de->inode != new_inode->i_ino))
763 goto try_again;
764 if (new_de->inode && !new_inode)
765 goto try_again;
766 if (old_de->inode != old_inode->i_ino)
767 goto try_again;
768
769 old_de->inode = 0;
770 new_de->inode = old_inode->i_ino;
771 old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
772 old_dir->i_dirt = 1;
773 old_dir->i_version = ++event;
774 new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
775 new_dir->i_dirt = 1;
776 new_dir->i_version = ++event;
777 if (new_inode) {
778 new_inode->i_nlink--;
779 new_inode->i_ctime = CURRENT_TIME;
780 new_inode->i_dirt = 1;
781 }
782 mark_buffer_dirty(old_bh, 1);
783 mark_buffer_dirty(new_bh, 1);
784 if (dir_bh) {
785 PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
786 mark_buffer_dirty(dir_bh, 1);
787 old_dir->i_nlink--;
788 old_dir->i_dirt = 1;
789 if (new_inode) {
790 new_inode->i_nlink--;
791 new_inode->i_dirt = 1;
792 } else {
793 new_dir->i_nlink++;
794 new_dir->i_dirt = 1;
795 }
796 }
797 retval = 0;
798 end_rename:
799 brelse(dir_bh);
800 brelse(old_bh);
801 brelse(new_bh);
802 iput(old_inode);
803 iput(new_inode);
804 iput(old_dir);
805 iput(new_dir);
806 return retval;
807 }
808
809
810
811
812
813
814
815
816
817
818 int minix_rename(struct inode * old_dir, const char * old_name, int old_len,
819 struct inode * new_dir, const char * new_name, int new_len)
820 {
821 static struct wait_queue * wait = NULL;
822 static int lock = 0;
823 int result;
824
825 while (lock)
826 sleep_on(&wait);
827 lock = 1;
828 result = do_minix_rename(old_dir, old_name, old_len,
829 new_dir, new_name, new_len);
830 lock = 0;
831 wake_up(&wait);
832 return result;
833 }