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
;
71 if (namelen
> SYSV_NAMELEN
) {
73 namelen
= SYSV_NAMELEN
;
78 pos
= block
= offset
= 0;
79 while (pos
< dir
->i_size
) {
81 bh
= sysv_file_bread(dir
, block
, 0);
83 /* offset = 0; */ block
++;
84 pos
+= sb
->sv_block_size
;
88 if (sysv_match(namelen
, name
,
89 *res_dir
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
) ))
92 offset
+= SYSV_DIRSIZE
;
93 if (offset
< sb
->sv_block_size
)
104 struct dentry
*sysv_lookup(struct inode
* dir
, struct dentry
* dentry
)
106 struct inode
* inode
= NULL
;
107 struct sysv_dir_entry
* de
;
108 struct buffer_head
* bh
;
110 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
, &de
);
115 inode
= iget(dir
->i_sb
, ino
);
118 return ERR_PTR(-EACCES
);
120 d_add(dentry
, inode
);
127 * adds a file entry to the specified directory, returning a possible
128 * error value if it fails.
130 * NOTE!! The inode part of 'de' is left at 0 - which means you
131 * may not sleep between calling this and putting something into
132 * the entry, as someone else might have used it while you slept.
134 static int sysv_add_entry(struct inode
* dir
,
135 const char * name
, int namelen
,
136 struct buffer_head
** res_buf
,
137 struct sysv_dir_entry
** res_dir
)
139 struct super_block
* sb
;
141 unsigned long pos
, block
, offset
; /* pos = block * block_size + offset */
142 struct buffer_head
* bh
;
143 struct sysv_dir_entry
* de
;
150 if (namelen
> SYSV_NAMELEN
) {
152 namelen
= SYSV_NAMELEN
;
154 return -ENAMETOOLONG
;
159 pos
= block
= offset
= 0;
162 bh
= sysv_file_bread(dir
, block
, 1);
166 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
);
168 offset
+= SYSV_DIRSIZE
;
169 if (pos
> dir
->i_size
) {
172 mark_inode_dirty(dir
);
175 if (namecompare(namelen
, SYSV_NAMELEN
, name
, de
->name
)) {
180 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME
;
181 mark_inode_dirty(dir
);
182 for (i
= 0; i
< SYSV_NAMELEN
; i
++)
183 de
->name
[i
] = (i
< namelen
) ? name
[i
] : 0;
184 mark_buffer_dirty(bh
, 1);
188 if (offset
< sb
->sv_block_size
)
198 int sysv_create(struct inode
* dir
, struct dentry
* dentry
, int mode
)
201 struct inode
* inode
;
202 struct buffer_head
* bh
;
203 struct sysv_dir_entry
* de
;
205 inode
= sysv_new_inode(dir
);
208 inode
->i_op
= &sysv_file_inode_operations
;
209 inode
->i_mode
= mode
;
210 mark_inode_dirty(inode
);
211 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
212 dentry
->d_name
.len
, &bh
, &de
);
215 mark_inode_dirty(inode
);
219 de
->inode
= inode
->i_ino
;
220 mark_buffer_dirty(bh
, 1);
222 d_instantiate(dentry
, inode
);
226 int sysv_mknod(struct inode
* dir
, struct dentry
* dentry
, int mode
, int rdev
)
229 struct inode
* inode
;
230 struct buffer_head
* bh
;
231 struct sysv_dir_entry
* de
;
233 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
234 dentry
->d_name
.len
, &de
);
239 inode
= sysv_new_inode(dir
);
242 inode
->i_uid
= current
->fsuid
;
243 init_special_inode(inode
, mode
, rdev
);
244 mark_inode_dirty(inode
);
245 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
246 dentry
->d_name
.len
, &bh
, &de
);
249 mark_inode_dirty(inode
);
253 de
->inode
= inode
->i_ino
;
254 mark_buffer_dirty(bh
, 1);
256 d_instantiate(dentry
, inode
);
260 int sysv_mkdir(struct inode
* dir
, struct dentry
*dentry
, int mode
)
263 struct inode
* inode
;
264 struct buffer_head
* bh
, *dir_block
;
265 struct sysv_dir_entry
* de
;
267 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
268 dentry
->d_name
.len
, &de
);
273 if (dir
->i_nlink
>= dir
->i_sb
->sv_link_max
)
275 inode
= sysv_new_inode(dir
);
278 inode
->i_op
= &sysv_dir_inode_operations
;
279 inode
->i_size
= 2 * SYSV_DIRSIZE
;
280 dir_block
= sysv_file_bread(inode
,0,1);
283 mark_inode_dirty(inode
);
287 de
= (struct sysv_dir_entry
*) (dir_block
->b_data
+ 0*SYSV_DIRSIZE
);
288 de
->inode
= inode
->i_ino
;
289 strcpy(de
->name
,"."); /* rest of de->name is zero, see sysv_new_block */
290 de
= (struct sysv_dir_entry
*) (dir_block
->b_data
+ 1*SYSV_DIRSIZE
);
291 de
->inode
= dir
->i_ino
;
292 strcpy(de
->name
,".."); /* rest of de->name is zero, see sysv_new_block */
294 mark_buffer_dirty(dir_block
, 1);
296 inode
->i_mode
= S_IFDIR
| (mode
& 0777 & ~current
->fs
->umask
);
297 if (dir
->i_mode
& S_ISGID
)
298 inode
->i_mode
|= S_ISGID
;
299 mark_inode_dirty(inode
);
300 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
301 dentry
->d_name
.len
, &bh
, &de
);
307 de
->inode
= inode
->i_ino
;
308 mark_buffer_dirty(bh
, 1);
310 mark_inode_dirty(dir
);
312 d_instantiate(dentry
, inode
);
317 * routine to check that the specified directory is empty (for rmdir)
319 static int empty_dir(struct inode
* inode
)
321 struct super_block
* sb
;
322 unsigned long pos
, block
, offset
; /* pos = block * block_size + offset */
323 struct buffer_head
* bh
;
324 struct sysv_dir_entry
* de
;
330 pos
= offset
= 2*SYSV_DIRSIZE
;
331 if (inode
->i_size
% SYSV_DIRSIZE
)
333 if (inode
->i_size
< pos
)
335 bh
= sysv_file_bread(inode
, 0, 0);
338 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ 0*SYSV_DIRSIZE
);
339 if (!de
->inode
|| strcmp(de
->name
,"."))
341 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ 1*SYSV_DIRSIZE
);
342 if (!de
->inode
|| strcmp(de
->name
,".."))
345 while (pos
< inode
->i_size
) {
347 bh
= sysv_file_bread(inode
, block
, 0);
349 /* offset = 0; */ block
++;
350 pos
+= sb
->sv_block_size
;
354 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
);
356 offset
+= SYSV_DIRSIZE
;
361 if (offset
< sb
->sv_block_size
)
371 printk("Bad directory on device %s\n",
372 kdevname(inode
->i_dev
));
376 int sysv_rmdir(struct inode
* dir
, struct dentry
* dentry
)
379 struct inode
* inode
;
380 struct buffer_head
* bh
;
381 struct sysv_dir_entry
* de
;
384 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
385 dentry
->d_name
.len
, &de
);
389 inode
= dentry
->d_inode
;
391 if (!empty_dir(inode
)) {
395 if (de
->inode
!= inode
->i_ino
) {
399 if (!list_empty(&dentry
->d_hash
)) {
403 if (inode
->i_nlink
!= 2)
404 printk("empty directory has nlink!=2 (%d)\n", inode
->i_nlink
);
406 mark_buffer_dirty(bh
, 1);
408 mark_inode_dirty(inode
);
410 inode
->i_ctime
= dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
411 mark_inode_dirty(dir
);
419 int sysv_unlink(struct inode
* dir
, struct dentry
* dentry
)
422 struct inode
* inode
;
423 struct buffer_head
* bh
;
424 struct sysv_dir_entry
* de
;
429 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
430 dentry
->d_name
.len
, &de
);
433 inode
= dentry
->d_inode
;
436 if (de
->inode
!= inode
->i_ino
) {
438 current
->counter
= 0;
442 if (de
->inode
!= inode
->i_ino
) {
446 if (!inode
->i_nlink
) {
447 printk("Deleting nonexistent file (%s:%lu), %d\n",
448 kdevname(inode
->i_dev
), inode
->i_ino
, inode
->i_nlink
);
452 mark_buffer_dirty(bh
, 1);
453 dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
454 mark_inode_dirty(dir
);
456 inode
->i_ctime
= dir
->i_ctime
;
457 mark_inode_dirty(inode
);
465 int sysv_symlink(struct inode
* dir
, struct dentry
* dentry
,
466 const char * symname
)
468 struct sysv_dir_entry
* de
;
469 struct inode
* inode
;
470 struct buffer_head
* name_block
;
471 char * name_block_data
;
472 struct super_block
* sb
;
475 struct buffer_head
* bh
;
477 if (!(inode
= sysv_new_inode(dir
)))
480 inode
->i_mode
= S_IFLNK
| 0777;
481 inode
->i_op
= &sysv_symlink_inode_operations
;
482 name_block
= sysv_file_bread(inode
, 0, 1);
485 mark_inode_dirty(inode
);
490 name_block_data
= name_block
->b_data
;
492 while (i
< sb
->sv_block_size_1
&& (c
= *(symname
++)))
493 name_block_data
[i
++] = c
;
494 name_block_data
[i
] = 0;
495 mark_buffer_dirty(name_block
, 1);
498 mark_inode_dirty(inode
);
499 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
500 dentry
->d_name
.len
, &de
);
503 mark_inode_dirty(inode
);
508 i
= sysv_add_entry(dir
, dentry
->d_name
.name
,
509 dentry
->d_name
.len
, &bh
, &de
);
512 mark_inode_dirty(inode
);
516 de
->inode
= inode
->i_ino
;
517 mark_buffer_dirty(bh
, 1);
519 d_instantiate(dentry
, inode
);
523 int sysv_link(struct dentry
* old_dentry
, struct inode
* dir
,
524 struct dentry
* dentry
)
526 struct inode
*oldinode
= old_dentry
->d_inode
;
528 struct sysv_dir_entry
* de
;
529 struct buffer_head
* bh
;
531 if (S_ISDIR(oldinode
->i_mode
)) {
534 if (oldinode
->i_nlink
>= oldinode
->i_sb
->sv_link_max
) {
537 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
538 dentry
->d_name
.len
, &de
);
543 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
544 dentry
->d_name
.len
, &bh
, &de
);
549 de
->inode
= oldinode
->i_ino
;
550 mark_buffer_dirty(bh
, 1);
553 oldinode
->i_ctime
= CURRENT_TIME
;
554 mark_inode_dirty(oldinode
);
556 d_instantiate(dentry
, oldinode
);
560 #define PARENT_INO(buffer) \
561 (((struct sysv_dir_entry *) ((buffer) + 1*SYSV_DIRSIZE))->inode)
564 * rename uses retrying to avoid race-conditions: at least they should be minimal.
565 * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
566 * checks fail, it tries to restart itself again. Very practical - no changes
567 * are done until we know everything works ok.. and then all the changes can be
568 * done in one fell swoop when we have claimed all the buffers needed.
570 * Anybody can rename anything with this: the permission checks are left to the
571 * higher-level routines.
573 int sysv_rename(struct inode
* old_dir
, struct dentry
* old_dentry
,
574 struct inode
* new_dir
, struct dentry
* new_dentry
)
576 struct inode
* old_inode
, * new_inode
;
577 struct buffer_head
* old_bh
, * new_bh
, * dir_bh
;
578 struct sysv_dir_entry
* old_de
, * new_de
;
586 current
->counter
= 0;
589 old_inode
= new_inode
= NULL
;
590 old_bh
= new_bh
= dir_bh
= NULL
;
591 old_bh
= sysv_find_entry(old_dir
, old_dentry
->d_name
.name
,
592 old_dentry
->d_name
.len
, &old_de
);
596 old_inode
= old_dentry
->d_inode
; /* don't cross mnt-points */
598 new_inode
= new_dentry
->d_inode
;
599 new_bh
= sysv_find_entry(new_dir
, new_dentry
->d_name
.name
,
600 new_dentry
->d_name
.len
, &new_de
);
607 if (S_ISDIR(old_inode
->i_mode
)) {
610 if (!empty_dir(new_inode
))
614 dir_bh
= sysv_file_bread(old_inode
, 0, 0);
617 if (PARENT_INO(dir_bh
->b_data
) != old_dir
->i_ino
)
620 if (!new_inode
&& new_dir
->i_nlink
>= new_dir
->i_sb
->sv_link_max
)
624 retval
= sysv_add_entry(new_dir
, new_dentry
->d_name
.name
,
625 new_dentry
->d_name
.len
, &new_bh
, &new_de
);
629 /* sanity checking before doing the rename - avoid races */
630 if (new_inode
&& (new_de
->inode
!= new_inode
->i_ino
))
632 if (new_de
->inode
&& !new_inode
)
634 if (old_de
->inode
!= old_inode
->i_ino
)
638 new_de
->inode
= old_inode
->i_ino
;
639 old_dir
->i_ctime
= old_dir
->i_mtime
= CURRENT_TIME
;
640 mark_inode_dirty(old_dir
);
641 new_dir
->i_ctime
= new_dir
->i_mtime
= CURRENT_TIME
;
642 mark_inode_dirty(new_dir
);
644 new_inode
->i_nlink
--;
645 new_inode
->i_ctime
= CURRENT_TIME
;
646 mark_inode_dirty(new_inode
);
648 mark_buffer_dirty(old_bh
, 1);
649 mark_buffer_dirty(new_bh
, 1);
651 PARENT_INO(dir_bh
->b_data
) = new_dir
->i_ino
;
652 mark_buffer_dirty(dir_bh
, 1);
654 mark_inode_dirty(old_dir
);
656 new_inode
->i_nlink
--;
657 mark_inode_dirty(new_inode
);
660 mark_inode_dirty(new_dir
);