4 * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
8 * linux/fs/minix/namei.c
10 * Copyright (C) 1991, 1992 Linus Torvalds
13 #include <linux/sched.h>
14 #include <linux/ext_fs.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/stat.h>
18 #include <linux/fcntl.h>
19 #include <linux/errno.h>
21 #include <asm/segment.h>
24 * comment out this line if you want names > EXT_NAME_LEN chars to be
25 * truncated. Else they will be disallowed.
27 /* #define NO_TRUNCATE */
30 * EXT_DIR_PAD defines the directory entries boundaries
32 * NOTE: It must be a power of 2 and must be greater or equal than 8
33 * because a directory entry needs 8 bytes for its fixed part
34 * (4 bytes for the inode, 2 bytes for the entry length and 2 bytes
35 * for the name length)
41 * EXT_DIR_MIN_SIZE is the minimal size of a directory entry
43 * During allocations, a directory entry is split into 2 ones
44 * *ONLY* if the size of the unused part is greater than or
45 * equal to EXT_DIR_MIN_SIZE
47 #define EXT_DIR_MIN_SIZE 12
50 * ok, we cannot use strncmp, as the name is not in our data space.
51 * Thus we'll have to use ext_match. No big problem. Match also makes
54 * NOTE! unlike strncmp, ext_match returns 1 for success, 0 for failure.
56 static int ext_match(int len
,const char * name
,struct ext_dir_entry
* de
)
58 register int same
__asm__("ax");
60 if (!de
|| !de
->inode
|| len
> EXT_NAME_LEN
)
62 /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
63 if (!len
&& (de
->name
[0]=='.') && (de
->name
[1]=='\0'))
65 if (len
< EXT_NAME_LEN
&& len
!= de
->name_len
)
71 :"0" (0),"S" ((long) name
),"D" ((long) de
->name
),"c" (len
)
79 * finds an entry in the specified directory with the wanted name. It
80 * returns the cache buffer in which the entry was found, and the entry
81 * itself (as a parameter - res_dir). It does NOT read the inode of the
82 * entry - you'll have to do that yourself if you want to.
84 * addition for the ext file system : this function returns the previous
85 * and next directory entries in the parameters prev_dir and next_dir
87 static struct buffer_head
* ext_find_entry(struct inode
* dir
,
88 const char * name
, int namelen
, struct ext_dir_entry
** res_dir
,
89 struct ext_dir_entry
** prev_dir
, struct ext_dir_entry
** next_dir
)
92 struct buffer_head
* bh
;
93 struct ext_dir_entry
* de
;
99 if (namelen
> EXT_NAME_LEN
)
102 if (namelen
> EXT_NAME_LEN
)
103 namelen
= EXT_NAME_LEN
;
105 bh
= ext_bread(dir
,0,0);
113 de
= (struct ext_dir_entry
*) bh
->b_data
;
114 while (offset
< dir
->i_size
) {
115 if ((char *)de
>= BLOCK_SIZE
+bh
->b_data
) {
118 bh
= ext_bread(dir
,offset
>>BLOCK_SIZE_BITS
,0);
121 de
= (struct ext_dir_entry
*) bh
->b_data
;
125 if (de
->rec_len
< 8 || de
->rec_len
% 8 != 0 ||
126 de
->rec_len
< de
->name_len
+ 8 ||
127 (((char *) de
) + de
->rec_len
-1 >= BLOCK_SIZE
+bh
->b_data
)) {
128 printk ("ext_find_entry: bad dir entry\n");
129 printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
130 dir
->i_dev
, dir
->i_ino
, offset
, de
->rec_len
, de
->name_len
);
131 de
= (struct ext_dir_entry
*) (bh
->b_data
+BLOCK_SIZE
);
132 offset
= ((offset
/ BLOCK_SIZE
) + 1) * BLOCK_SIZE
;
137 if (ext_match(namelen
,name
,de
)) {
140 if (offset
+ de
->rec_len
< dir
->i_size
&&
141 ((char *)de
) + de
->rec_len
< BLOCK_SIZE
+bh
->b_data
)
142 *next_dir
= (struct ext_dir_entry
*)
143 ((char *) de
+ de
->rec_len
);
148 offset
+= de
->rec_len
;
151 de
= (struct ext_dir_entry
*) ((char *) de
+ de
->rec_len
);
157 int ext_lookup(struct inode
* dir
,const char * name
, int len
,
158 struct inode
** result
)
161 struct ext_dir_entry
* de
;
162 struct buffer_head
* bh
;
167 if (!S_ISDIR(dir
->i_mode
)) {
171 if (!(bh
= ext_find_entry(dir
,name
,len
,&de
,NULL
,NULL
))) {
177 if (!(*result
= iget(dir
->i_sb
,ino
))) {
188 * adds a file entry to the specified directory, using the same
189 * semantics as ext_find_entry(). It returns NULL if it failed.
191 * NOTE!! The inode part of 'de' is left at 0 - which means you
192 * may not sleep between calling this and putting something into
193 * the entry, as someone else might have used it while you slept.
195 static struct buffer_head
* ext_add_entry(struct inode
* dir
,
196 const char * name
, int namelen
, struct ext_dir_entry
** res_dir
)
200 unsigned short rec_len
;
201 struct buffer_head
* bh
;
202 struct ext_dir_entry
* de
, * de1
;
208 if (namelen
> EXT_NAME_LEN
)
211 if (namelen
> EXT_NAME_LEN
)
212 namelen
= EXT_NAME_LEN
;
216 bh
= ext_bread(dir
,0,0);
219 rec_len
= ((8 + namelen
+ EXT_DIR_PAD
- 1) / EXT_DIR_PAD
) * EXT_DIR_PAD
;
221 de
= (struct ext_dir_entry
*) bh
->b_data
;
223 if ((char *)de
>= BLOCK_SIZE
+bh
->b_data
&& offset
< dir
->i_size
) {
225 printk ("ext_add_entry: skipping to next block\n");
229 bh
= ext_bread(dir
,offset
>>BLOCK_SIZE_BITS
,0);
232 de
= (struct ext_dir_entry
*) bh
->b_data
;
234 if (offset
>= dir
->i_size
) {
235 /* Check that the directory entry fits in the block */
236 if (offset
% BLOCK_SIZE
== 0 ||
237 (BLOCK_SIZE
- (offset
% BLOCK_SIZE
)) < rec_len
) {
238 if ((offset
% BLOCK_SIZE
) != 0) {
239 /* If the entry does not fit in the
240 block, the remainder of the block
241 becomes an unused entry */
243 de
->rec_len
= BLOCK_SIZE
244 - (offset
& (BLOCK_SIZE
- 1));
246 offset
+= de
->rec_len
;
247 dir
->i_size
+= de
->rec_len
;
250 dir
->i_ctime
= CURRENT_TIME
;
257 printk ("ext_add_entry : creating next block\n");
259 bh
= ext_bread(dir
,offset
>>BLOCK_SIZE_BITS
,1);
261 return NULL
; /* Other thing to do ??? */
262 de
= (struct ext_dir_entry
*) bh
->b_data
;
264 /* Allocate the entry */
266 de
->rec_len
= rec_len
;
267 dir
->i_size
+= de
->rec_len
;
270 dir
->i_ctime
= CURRENT_TIME
;
273 if (de
->rec_len
< 8 || de
->rec_len
% 4 != 0 ||
274 de
->rec_len
< de
->name_len
+ 8 ||
275 (((char *) de
) + de
->rec_len
-1 >= BLOCK_SIZE
+bh
->b_data
)) {
276 printk ("ext_addr_entry: bad dir entry\n");
277 printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
278 dir
->i_dev
, dir
->i_ino
, offset
, de
->rec_len
, de
->name_len
);
282 if (!de
->inode
&& de
->rec_len
>= rec_len
) {
283 if (de
->rec_len
> rec_len
284 && de
->rec_len
- rec_len
>= EXT_DIR_MIN_SIZE
) {
285 /* The found entry is too big : it is split
287 - the 1st one will be used to hold the name,
288 - the 2nd one is unused */
289 de1
= (struct ext_dir_entry
*) ((char *) de
+ rec_len
);
291 de1
->rec_len
= de
->rec_len
- rec_len
;
293 de
->rec_len
= rec_len
;
295 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME
;
296 de
->name_len
= namelen
;
297 for (i
=0; i
< namelen
; i
++)
298 de
->name
[i
] = name
[i
];
303 offset
+= de
->rec_len
;
304 de
= (struct ext_dir_entry
*) ((char *) de
+ de
->rec_len
);
310 int ext_create(struct inode
* dir
,const char * name
, int len
, int mode
,
311 struct inode
** result
)
313 struct inode
* inode
;
314 struct buffer_head
* bh
;
315 struct ext_dir_entry
* de
;
320 inode
= ext_new_inode(dir
);
325 inode
->i_op
= &ext_file_inode_operations
;
326 inode
->i_mode
= mode
;
328 bh
= ext_add_entry(dir
,name
,len
,&de
);
336 de
->inode
= inode
->i_ino
;
344 int ext_mknod(struct inode
* dir
, const char * name
, int len
, int mode
, int rdev
)
346 struct inode
* inode
;
347 struct buffer_head
* bh
;
348 struct ext_dir_entry
* de
;
352 bh
= ext_find_entry(dir
,name
,len
,&de
,NULL
,NULL
);
358 inode
= ext_new_inode(dir
);
363 inode
->i_uid
= current
->euid
;
364 inode
->i_mode
= mode
;
366 if (S_ISREG(inode
->i_mode
))
367 inode
->i_op
= &ext_file_inode_operations
;
368 else if (S_ISDIR(inode
->i_mode
)) {
369 inode
->i_op
= &ext_dir_inode_operations
;
370 if (dir
->i_mode
& S_ISGID
)
371 inode
->i_mode
|= S_ISGID
;
373 else if (S_ISLNK(inode
->i_mode
))
374 inode
->i_op
= &ext_symlink_inode_operations
;
375 else if (S_ISCHR(inode
->i_mode
))
376 inode
->i_op
= &chrdev_inode_operations
;
377 else if (S_ISBLK(inode
->i_mode
))
378 inode
->i_op
= &blkdev_inode_operations
;
379 else if (S_ISFIFO(inode
->i_mode
))
381 if (S_ISBLK(mode
) || S_ISCHR(mode
))
382 inode
->i_rdev
= rdev
;
384 inode
->i_mtime
= inode
->i_atime
= CURRENT_TIME
;
387 bh
= ext_add_entry(dir
,name
,len
,&de
);
395 de
->inode
= inode
->i_ino
;
403 int ext_mkdir(struct inode
* dir
, const char * name
, int len
, int mode
)
405 struct inode
* inode
;
406 struct buffer_head
* bh
, *dir_block
;
407 struct ext_dir_entry
* de
;
409 bh
= ext_find_entry(dir
,name
,len
,&de
,NULL
,NULL
);
415 inode
= ext_new_inode(dir
);
420 inode
->i_op
= &ext_dir_inode_operations
;
421 inode
->i_size
= 2 * 16; /* Each entry is coded on 16 bytes for "." and ".."
422 - 4 bytes for the inode number,
423 - 2 bytes for the record length
424 - 2 bytes for the name length
425 - 8 bytes for the name */
427 inode
->i_mtime
= inode
->i_atime
= CURRENT_TIME
;
429 dir_block
= ext_bread(inode
,0,1);
437 de
= (struct ext_dir_entry
*) dir_block
->b_data
;
438 de
->inode
=inode
->i_ino
;
441 strcpy(de
->name
,".");
442 de
= (struct ext_dir_entry
*) ((char *) de
+ de
->rec_len
);
443 de
->inode
= dir
->i_ino
;
446 strcpy(de
->name
,"..");
448 dir_block
->b_dirt
= 1;
450 inode
->i_mode
= S_IFDIR
| (mode
& 0777 & ~current
->umask
);
451 if (dir
->i_mode
& S_ISGID
)
452 inode
->i_mode
|= S_ISGID
;
454 bh
= ext_add_entry(dir
,name
,len
,&de
);
461 de
->inode
= inode
->i_ino
;
472 * routine to check that the specified directory is empty (for rmdir)
474 static int empty_dir(struct inode
* inode
)
476 unsigned long offset
;
477 struct buffer_head
* bh
;
478 struct ext_dir_entry
* de
, * de1
;
480 if (inode
->i_size
< 2 * 12 || !(bh
= ext_bread(inode
,0,0))) {
481 printk("warning - bad directory on dev %04x\n",inode
->i_dev
);
484 de
= (struct ext_dir_entry
*) bh
->b_data
;
485 de1
= (struct ext_dir_entry
*) ((char *) de
+ de
->rec_len
);
486 if (de
->inode
!= inode
->i_ino
|| !de1
->inode
||
487 strcmp(".",de
->name
) || strcmp("..",de1
->name
)) {
488 printk("warning - bad directory on dev %04x\n",inode
->i_dev
);
491 offset
= de
->rec_len
+ de1
->rec_len
;
492 de
= (struct ext_dir_entry
*) ((char *) de1
+ de1
->rec_len
);
493 while (offset
< inode
->i_size
) {
494 if ((void *) de
>= (void *) (bh
->b_data
+BLOCK_SIZE
)) {
496 bh
= ext_bread(inode
, offset
>> BLOCK_SIZE_BITS
,1);
498 offset
+= BLOCK_SIZE
;
501 de
= (struct ext_dir_entry
*) bh
->b_data
;
503 if (de
->rec_len
< 8 || de
->rec_len
%4 != 0 ||
504 de
->rec_len
< de
->name_len
+ 8) {
505 printk ("empty_dir: bad dir entry\n");
506 printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
507 inode
->i_dev
, inode
->i_ino
, offset
, de
->rec_len
, de
->name_len
);
515 offset
+= de
->rec_len
;
516 de
= (struct ext_dir_entry
*) ((char *) de
+ de
->rec_len
);
522 static inline void ext_merge_entries (struct ext_dir_entry
* de
,
523 struct ext_dir_entry
* pde
, struct ext_dir_entry
* nde
)
525 if (nde
&& !nde
->inode
)
526 de
->rec_len
+= nde
->rec_len
;
527 if (pde
&& !pde
->inode
)
528 pde
->rec_len
+= de
->rec_len
;
531 int ext_rmdir(struct inode
* dir
, const char * name
, int len
)
534 struct inode
* inode
;
535 struct buffer_head
* bh
;
536 struct ext_dir_entry
* de
, * pde
, * nde
;
539 bh
= ext_find_entry(dir
,name
,len
,&de
,&pde
,&nde
);
544 if (!(inode
= iget(dir
->i_sb
, de
->inode
)))
546 if ((dir
->i_mode
& S_ISVTX
) && current
->euid
&&
547 inode
->i_uid
!= current
->euid
)
549 if (inode
->i_dev
!= dir
->i_dev
)
551 if (inode
== dir
) /* we may not delete ".", but "../dir" is ok */
553 if (!S_ISDIR(inode
->i_mode
)) {
557 if (!empty_dir(inode
)) {
561 if (inode
->i_count
> 1) {
565 if (inode
->i_nlink
!= 2)
566 printk("empty directory has nlink!=2 (%d)\n",inode
->i_nlink
);
569 ext_merge_entries (de
, pde
, nde
);
574 inode
->i_ctime
= dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
584 int ext_unlink(struct inode
* dir
, const char * name
, int len
)
587 struct inode
* inode
;
588 struct buffer_head
* bh
;
589 struct ext_dir_entry
* de
, * pde
, * nde
;
593 bh
= ext_find_entry(dir
,name
,len
,&de
,&pde
,&nde
);
596 if (!(inode
= iget(dir
->i_sb
, de
->inode
)))
599 if ((dir
->i_mode
& S_ISVTX
) && !suser() &&
600 current
->euid
!= inode
->i_uid
&&
601 current
->euid
!= dir
->i_uid
)
603 if (S_ISDIR(inode
->i_mode
))
605 if (!inode
->i_nlink
) {
606 printk("Deleting nonexistent file (%04x:%d), %d\n",
607 inode
->i_dev
,inode
->i_ino
,inode
->i_nlink
);
612 ext_merge_entries (de
, pde
, nde
);
616 inode
->i_ctime
= CURRENT_TIME
;
617 dir
->i_ctime
= dir
->i_mtime
= inode
->i_ctime
;
627 int ext_symlink(struct inode
* dir
, const char * name
, int len
, const char * symname
)
629 struct ext_dir_entry
* de
;
630 struct inode
* inode
= NULL
;
631 struct buffer_head
* bh
= NULL
, * name_block
= NULL
;
635 if (!(inode
= ext_new_inode(dir
))) {
639 inode
->i_mode
= S_IFLNK
| 0777;
640 inode
->i_op
= &ext_symlink_inode_operations
;
641 name_block
= ext_bread(inode
,0,1);
650 while (i
< 1023 && (c
= *(symname
++)))
651 name_block
->b_data
[i
++] = c
;
652 name_block
->b_data
[i
] = 0;
653 name_block
->b_dirt
= 1;
657 bh
= ext_find_entry(dir
,name
,len
,&de
,NULL
,NULL
);
666 bh
= ext_add_entry(dir
,name
,len
,&de
);
674 de
->inode
= inode
->i_ino
;
682 int ext_link(struct inode
* oldinode
, struct inode
* dir
, const char * name
, int len
)
684 struct ext_dir_entry
* de
;
685 struct buffer_head
* bh
;
687 if (S_ISDIR(oldinode
->i_mode
)) {
692 if (oldinode
->i_nlink
> 32000) {
697 bh
= ext_find_entry(dir
,name
,len
,&de
,NULL
,NULL
);
704 bh
= ext_add_entry(dir
,name
,len
,&de
);
710 de
->inode
= oldinode
->i_ino
;
715 oldinode
->i_ctime
= CURRENT_TIME
;
716 oldinode
->i_dirt
= 1;
721 static int subdir(struct inode
* new_inode
, struct inode
* old_inode
)
726 new_inode
->i_count
++;
729 if (new_inode
== old_inode
) {
733 if (new_inode
->i_dev
!= old_inode
->i_dev
)
735 ino
= new_inode
->i_ino
;
736 if (ext_lookup(new_inode
,"..",2,&new_inode
))
738 if (new_inode
->i_ino
== ino
)
745 #define PARENT_INO(buffer) \
746 ((struct ext_dir_entry *) ((char *) buffer + \
747 ((struct ext_dir_entry *) buffer)->rec_len))->inode
749 #define PARENT_NAME(buffer) \
750 ((struct ext_dir_entry *) ((char *) buffer + \
751 ((struct ext_dir_entry *) buffer)->rec_len))->name
754 * rename uses retrying to avoid race-conditions: at least they should be minimal.
755 * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
756 * checks fail, it tries to restart itself again. Very practical - no changes
757 * are done until we know everything works ok.. and then all the changes can be
758 * done in one fell swoop when we have claimed all the buffers needed.
760 * Anybody can rename anything with this: the permission checks are left to the
761 * higher-level routines.
763 static int do_ext_rename(struct inode
* old_dir
, const char * old_name
, int old_len
,
764 struct inode
* new_dir
, const char * new_name
, int new_len
)
766 struct inode
* old_inode
, * new_inode
;
767 struct buffer_head
* old_bh
, * new_bh
, * dir_bh
;
768 struct ext_dir_entry
* old_de
, * new_de
, * pde
, * nde
;
778 current
->counter
= 0;
781 old_inode
= new_inode
= NULL
;
782 old_bh
= new_bh
= dir_bh
= NULL
;
783 old_bh
= ext_find_entry(old_dir
,old_name
,old_len
,&old_de
,&pde
,&nde
);
787 old_inode
= __iget(old_dir
->i_sb
, old_de
->inode
,0); /* don't cross mnt-points */
791 if ((old_dir
->i_mode
& S_ISVTX
) &&
792 current
->euid
!= old_inode
->i_uid
&&
793 current
->euid
!= old_dir
->i_uid
&& !suser())
795 new_bh
= ext_find_entry(new_dir
,new_name
,new_len
,&new_de
,NULL
,NULL
);
797 new_inode
= __iget(new_dir
->i_sb
, new_de
->inode
,0); /* don't cross mnt-points */
803 if (new_inode
== old_inode
) {
807 if (new_inode
&& S_ISDIR(new_inode
->i_mode
)) {
812 if (new_inode
&& (new_dir
->i_mode
& S_ISVTX
) &&
813 current
->euid
!= new_inode
->i_uid
&&
814 current
->euid
!= new_dir
->i_uid
&& !suser())
816 if (S_ISDIR(old_inode
->i_mode
)) {
821 if (!permission(old_inode
, MAY_WRITE
))
824 if (subdir(new_dir
, old_inode
))
827 dir_bh
= ext_bread(old_inode
,0,0);
830 if (PARENT_INO(dir_bh
->b_data
) != old_dir
->i_ino
)
834 new_bh
= ext_add_entry(new_dir
,new_name
,new_len
,&new_de
);
838 /* sanity checking before doing the rename - avoid races */
839 if (new_inode
&& (new_de
->inode
!= new_inode
->i_ino
))
841 if (new_de
->inode
&& !new_inode
)
843 if (old_de
->inode
!= old_inode
->i_ino
)
847 old_de
->name_len
= 0;
848 new_de
->inode
= old_inode
->i_ino
;
849 ext_merge_entries (old_de
, pde
, nde
);
851 new_inode
->i_nlink
--;
852 new_inode
->i_dirt
= 1;
857 PARENT_INO(dir_bh
->b_data
) = new_dir
->i_ino
;
877 * Ok, rename also locks out other renames, as they can change the parent of
878 * a directory, and we don't want any races. Other races are checked for by
879 * "do_rename()", which restarts if there are inconsistencies.
881 * Note that there is no race between different filesystems: it's only within
882 * the same device that races occur: many renames can happen at once, as long
883 * as they are on different partitions.
885 int ext_rename(struct inode
* old_dir
, const char * old_name
, int old_len
,
886 struct inode
* new_dir
, const char * new_name
, int new_len
)
888 static struct wait_queue
* wait
= NULL
;
895 result
= do_ext_rename(old_dir
, old_name
, old_len
,
896 new_dir
, new_name
, new_len
);