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