2 * linux/fs/sysv/namei.c
5 * Copyright (C) 1991, 1992 Linus Torvalds
8 * Copyright (C) 1993 Pascal Haible, Bruno Haible
11 * Copyright (C) 1993 Bruno Haible
12 * Copyright (C) 1997, 1998 Krzysztof G. Baranowski
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
19 #include <linux/sysv_fs.h>
20 #include <linux/string.h>
21 #include <linux/stat.h>
22 #include <linux/errno.h>
24 /* compare strings: name[0..len-1] (not zero-terminated) and
25 * buffer[0..] (filled with zeroes up to buffer[0..maxlen-1])
27 static inline int namecompare(int len
, int maxlen
,
28 const char * name
, const char * buffer
)
32 if (len
< maxlen
&& buffer
[len
])
34 return !memcmp(name
, buffer
, len
);
38 * ok, we cannot use strncmp, as the name is not in our data space. [Now it is!]
39 * Thus we'll have to use sysv_match. No big problem. Match also makes
42 * NOTE! unlike strncmp, sysv_match returns 1 for success, 0 for failure.
44 static int sysv_match(int len
, const char * name
, struct sysv_dir_entry
* de
)
46 if (!de
->inode
|| len
> SYSV_NAMELEN
)
48 /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
49 if (!len
&& (de
->name
[0]=='.') && (de
->name
[1]=='\0'))
51 return namecompare(len
, SYSV_NAMELEN
, name
, de
->name
);
57 * finds an entry in the specified directory with the wanted name. It
58 * returns the cache buffer in which the entry was found, and the entry
59 * itself (as a parameter - res_dir). It does NOT read the inode of the
60 * entry - you'll have to do that yourself if you want to.
62 static struct buffer_head
* sysv_find_entry(struct inode
* dir
,
63 const char * name
, int namelen
, struct sysv_dir_entry
** res_dir
)
65 struct super_block
* sb
;
66 unsigned long pos
, block
, offset
; /* pos = block * block_size + offset */
67 struct buffer_head
* bh
;
73 if (namelen
> SYSV_NAMELEN
) {
75 namelen
= SYSV_NAMELEN
;
80 pos
= block
= offset
= 0;
81 while (pos
< dir
->i_size
) {
83 bh
= sysv_file_bread(dir
, block
, 0);
85 /* offset = 0; */ block
++;
86 pos
+= sb
->sv_block_size
;
90 if (sysv_match(namelen
, name
,
91 *res_dir
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
) ))
94 offset
+= SYSV_DIRSIZE
;
95 if (offset
< sb
->sv_block_size
)
106 struct dentry
*sysv_lookup(struct inode
* dir
, struct dentry
* dentry
)
108 struct inode
* inode
= NULL
;
109 struct sysv_dir_entry
* de
;
110 struct buffer_head
* bh
;
112 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
, &de
);
117 inode
= iget(dir
->i_sb
, ino
);
120 return ERR_PTR(-EACCES
);
122 d_add(dentry
, inode
);
129 * adds a file entry to the specified directory, returning a possible
130 * error value if it fails.
132 * NOTE!! The inode part of 'de' is left at 0 - which means you
133 * may not sleep between calling this and putting something into
134 * the entry, as someone else might have used it while you slept.
136 static int sysv_add_entry(struct inode
* dir
,
137 const char * name
, int namelen
,
138 struct buffer_head
** res_buf
,
139 struct sysv_dir_entry
** res_dir
)
141 struct super_block
* sb
;
143 unsigned long pos
, block
, offset
; /* pos = block * block_size + offset */
144 struct buffer_head
* bh
;
145 struct sysv_dir_entry
* de
;
152 if (namelen
> SYSV_NAMELEN
) {
154 namelen
= SYSV_NAMELEN
;
156 return -ENAMETOOLONG
;
161 pos
= block
= offset
= 0;
164 bh
= sysv_file_bread(dir
, block
, 1);
168 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
);
170 offset
+= SYSV_DIRSIZE
;
171 if (pos
> dir
->i_size
) {
174 mark_inode_dirty(dir
);
177 if (namecompare(namelen
, SYSV_NAMELEN
, name
, de
->name
)) {
182 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME
;
183 mark_inode_dirty(dir
);
184 for (i
= 0; i
< SYSV_NAMELEN
; i
++)
185 de
->name
[i
] = (i
< namelen
) ? name
[i
] : 0;
186 mark_buffer_dirty(bh
, 1);
190 if (offset
< sb
->sv_block_size
)
200 int sysv_create(struct inode
* dir
, struct dentry
* dentry
, int mode
)
203 struct inode
* inode
;
204 struct buffer_head
* bh
;
205 struct sysv_dir_entry
* de
;
207 inode
= sysv_new_inode(dir
);
210 inode
->i_op
= &sysv_file_inode_operations
;
211 inode
->i_mode
= mode
;
212 mark_inode_dirty(inode
);
213 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
214 dentry
->d_name
.len
, &bh
, &de
);
217 mark_inode_dirty(inode
);
221 de
->inode
= inode
->i_ino
;
222 mark_buffer_dirty(bh
, 1);
224 d_instantiate(dentry
, inode
);
228 int sysv_mknod(struct inode
* dir
, struct dentry
* dentry
, int mode
, int rdev
)
231 struct inode
* inode
;
232 struct buffer_head
* bh
;
233 struct sysv_dir_entry
* de
;
235 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
236 dentry
->d_name
.len
, &de
);
241 inode
= sysv_new_inode(dir
);
244 inode
->i_uid
= current
->fsuid
;
245 inode
->i_mode
= mode
;
247 if (S_ISREG(inode
->i_mode
))
248 inode
->i_op
= &sysv_file_inode_operations
;
249 else if (S_ISCHR(inode
->i_mode
))
250 inode
->i_op
= &chrdev_inode_operations
;
251 else if (S_ISBLK(inode
->i_mode
))
252 inode
->i_op
= &blkdev_inode_operations
;
253 else if (S_ISFIFO(inode
->i_mode
))
255 if (S_ISBLK(mode
) || S_ISCHR(mode
))
256 inode
->i_rdev
= to_kdev_t(rdev
);
257 mark_inode_dirty(inode
);
258 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
259 dentry
->d_name
.len
, &bh
, &de
);
262 mark_inode_dirty(inode
);
266 de
->inode
= inode
->i_ino
;
267 mark_buffer_dirty(bh
, 1);
269 d_instantiate(dentry
, inode
);
273 int sysv_mkdir(struct inode
* dir
, struct dentry
*dentry
, int mode
)
276 struct inode
* inode
;
277 struct buffer_head
* bh
, *dir_block
;
278 struct sysv_dir_entry
* de
;
280 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
281 dentry
->d_name
.len
, &de
);
286 if (dir
->i_nlink
>= dir
->i_sb
->sv_link_max
)
288 inode
= sysv_new_inode(dir
);
291 inode
->i_op
= &sysv_dir_inode_operations
;
292 inode
->i_size
= 2 * SYSV_DIRSIZE
;
293 dir_block
= sysv_file_bread(inode
,0,1);
296 mark_inode_dirty(inode
);
300 de
= (struct sysv_dir_entry
*) (dir_block
->b_data
+ 0*SYSV_DIRSIZE
);
301 de
->inode
= inode
->i_ino
;
302 strcpy(de
->name
,"."); /* rest of de->name is zero, see sysv_new_block */
303 de
= (struct sysv_dir_entry
*) (dir_block
->b_data
+ 1*SYSV_DIRSIZE
);
304 de
->inode
= dir
->i_ino
;
305 strcpy(de
->name
,".."); /* rest of de->name is zero, see sysv_new_block */
307 mark_buffer_dirty(dir_block
, 1);
309 inode
->i_mode
= S_IFDIR
| (mode
& 0777 & ~current
->fs
->umask
);
310 if (dir
->i_mode
& S_ISGID
)
311 inode
->i_mode
|= S_ISGID
;
312 mark_inode_dirty(inode
);
313 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
314 dentry
->d_name
.len
, &bh
, &de
);
320 de
->inode
= inode
->i_ino
;
321 mark_buffer_dirty(bh
, 1);
323 mark_inode_dirty(dir
);
325 d_instantiate(dentry
, inode
);
330 * routine to check that the specified directory is empty (for rmdir)
332 static int empty_dir(struct inode
* inode
)
334 struct super_block
* sb
;
335 unsigned long pos
, block
, offset
; /* pos = block * block_size + offset */
336 struct buffer_head
* bh
;
337 struct sysv_dir_entry
* de
;
343 pos
= offset
= 2*SYSV_DIRSIZE
;
344 if (inode
->i_size
% SYSV_DIRSIZE
)
346 if (inode
->i_size
< pos
)
348 bh
= sysv_file_bread(inode
, 0, 0);
351 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ 0*SYSV_DIRSIZE
);
352 if (!de
->inode
|| strcmp(de
->name
,"."))
354 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ 1*SYSV_DIRSIZE
);
355 if (!de
->inode
|| strcmp(de
->name
,".."))
358 while (pos
< inode
->i_size
) {
360 bh
= sysv_file_bread(inode
, block
, 0);
362 /* offset = 0; */ block
++;
363 pos
+= sb
->sv_block_size
;
367 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
);
369 offset
+= SYSV_DIRSIZE
;
374 if (offset
< sb
->sv_block_size
)
384 printk("Bad directory on device %s\n",
385 kdevname(inode
->i_dev
));
389 int sysv_rmdir(struct inode
* dir
, struct dentry
* dentry
)
392 struct inode
* inode
;
393 struct buffer_head
* bh
;
394 struct sysv_dir_entry
* de
;
397 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
398 dentry
->d_name
.len
, &de
);
402 inode
= dentry
->d_inode
;
404 if (!empty_dir(inode
)) {
408 if (de
->inode
!= inode
->i_ino
) {
412 if (!list_empty(&dentry
->d_hash
)) {
416 if (inode
->i_nlink
!= 2)
417 printk("empty directory has nlink!=2 (%d)\n", inode
->i_nlink
);
419 mark_buffer_dirty(bh
, 1);
421 mark_inode_dirty(inode
);
423 inode
->i_ctime
= dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
424 mark_inode_dirty(dir
);
432 int sysv_unlink(struct inode
* dir
, struct dentry
* dentry
)
435 struct inode
* inode
;
436 struct buffer_head
* bh
;
437 struct sysv_dir_entry
* de
;
442 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
443 dentry
->d_name
.len
, &de
);
446 inode
= dentry
->d_inode
;
449 if (de
->inode
!= inode
->i_ino
) {
451 current
->counter
= 0;
455 if (de
->inode
!= inode
->i_ino
) {
459 if (!inode
->i_nlink
) {
460 printk("Deleting nonexistent file (%s:%lu), %d\n",
461 kdevname(inode
->i_dev
), inode
->i_ino
, inode
->i_nlink
);
465 mark_buffer_dirty(bh
, 1);
466 dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
467 mark_inode_dirty(dir
);
469 inode
->i_ctime
= dir
->i_ctime
;
470 mark_inode_dirty(inode
);
478 int sysv_symlink(struct inode
* dir
, struct dentry
* dentry
,
479 const char * symname
)
481 struct sysv_dir_entry
* de
;
482 struct inode
* inode
;
483 struct buffer_head
* name_block
;
484 char * name_block_data
;
485 struct super_block
* sb
;
488 struct buffer_head
* bh
;
490 if (!(inode
= sysv_new_inode(dir
)))
493 inode
->i_mode
= S_IFLNK
| 0777;
494 inode
->i_op
= &sysv_symlink_inode_operations
;
495 name_block
= sysv_file_bread(inode
, 0, 1);
498 mark_inode_dirty(inode
);
503 name_block_data
= name_block
->b_data
;
505 while (i
< sb
->sv_block_size_1
&& (c
= *(symname
++)))
506 name_block_data
[i
++] = c
;
507 name_block_data
[i
] = 0;
508 mark_buffer_dirty(name_block
, 1);
511 mark_inode_dirty(inode
);
512 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
513 dentry
->d_name
.len
, &de
);
516 mark_inode_dirty(inode
);
521 i
= sysv_add_entry(dir
, dentry
->d_name
.name
,
522 dentry
->d_name
.len
, &bh
, &de
);
525 mark_inode_dirty(inode
);
529 de
->inode
= inode
->i_ino
;
530 mark_buffer_dirty(bh
, 1);
532 d_instantiate(dentry
, inode
);
536 int sysv_link(struct dentry
* old_dentry
, struct inode
* dir
,
537 struct dentry
* dentry
)
539 struct inode
*oldinode
= old_dentry
->d_inode
;
541 struct sysv_dir_entry
* de
;
542 struct buffer_head
* bh
;
544 if (S_ISDIR(oldinode
->i_mode
)) {
547 if (oldinode
->i_nlink
>= oldinode
->i_sb
->sv_link_max
) {
550 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
551 dentry
->d_name
.len
, &de
);
556 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
557 dentry
->d_name
.len
, &bh
, &de
);
562 de
->inode
= oldinode
->i_ino
;
563 mark_buffer_dirty(bh
, 1);
566 oldinode
->i_ctime
= CURRENT_TIME
;
567 mark_inode_dirty(oldinode
);
569 d_instantiate(dentry
, oldinode
);
573 #define PARENT_INO(buffer) \
574 (((struct sysv_dir_entry *) ((buffer) + 1*SYSV_DIRSIZE))->inode)
577 * rename uses retrying to avoid race-conditions: at least they should be minimal.
578 * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
579 * checks fail, it tries to restart itself again. Very practical - no changes
580 * are done until we know everything works ok.. and then all the changes can be
581 * done in one fell swoop when we have claimed all the buffers needed.
583 * Anybody can rename anything with this: the permission checks are left to the
584 * higher-level routines.
586 int sysv_rename(struct inode
* old_dir
, struct dentry
* old_dentry
,
587 struct inode
* new_dir
, struct dentry
* new_dentry
)
589 struct inode
* old_inode
, * new_inode
;
590 struct buffer_head
* old_bh
, * new_bh
, * dir_bh
;
591 struct sysv_dir_entry
* old_de
, * new_de
;
599 current
->counter
= 0;
602 old_inode
= new_inode
= NULL
;
603 old_bh
= new_bh
= dir_bh
= NULL
;
604 old_bh
= sysv_find_entry(old_dir
, old_dentry
->d_name
.name
,
605 old_dentry
->d_name
.len
, &old_de
);
609 old_inode
= old_dentry
->d_inode
; /* don't cross mnt-points */
611 new_inode
= new_dentry
->d_inode
;
612 new_bh
= sysv_find_entry(new_dir
, new_dentry
->d_name
.name
,
613 new_dentry
->d_name
.len
, &new_de
);
620 if (S_ISDIR(old_inode
->i_mode
)) {
623 if (!empty_dir(new_inode
))
627 dir_bh
= sysv_file_bread(old_inode
, 0, 0);
630 if (PARENT_INO(dir_bh
->b_data
) != old_dir
->i_ino
)
633 if (!new_inode
&& new_dir
->i_nlink
>= new_dir
->i_sb
->sv_link_max
)
637 retval
= sysv_add_entry(new_dir
, new_dentry
->d_name
.name
,
638 new_dentry
->d_name
.len
, &new_bh
, &new_de
);
642 /* sanity checking before doing the rename - avoid races */
643 if (new_inode
&& (new_de
->inode
!= new_inode
->i_ino
))
645 if (new_de
->inode
&& !new_inode
)
647 if (old_de
->inode
!= old_inode
->i_ino
)
651 new_de
->inode
= old_inode
->i_ino
;
652 old_dir
->i_ctime
= old_dir
->i_mtime
= CURRENT_TIME
;
653 mark_inode_dirty(old_dir
);
654 new_dir
->i_ctime
= new_dir
->i_mtime
= CURRENT_TIME
;
655 mark_inode_dirty(new_dir
);
657 new_inode
->i_nlink
--;
658 new_inode
->i_ctime
= CURRENT_TIME
;
659 mark_inode_dirty(new_inode
);
661 mark_buffer_dirty(old_bh
, 1);
662 mark_buffer_dirty(new_bh
, 1);
664 PARENT_INO(dir_bh
->b_data
) = new_dir
->i_ino
;
665 mark_buffer_dirty(dir_bh
, 1);
667 mark_inode_dirty(old_dir
);
669 new_inode
->i_nlink
--;
670 mark_inode_dirty(new_inode
);
673 mark_inode_dirty(new_dir
);