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