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
;
148 if (namelen
> SYSV_NAMELEN
) {
150 namelen
= SYSV_NAMELEN
;
152 return -ENAMETOOLONG
;
157 pos
= block
= offset
= 0;
160 bh
= sysv_file_bread(dir
, block
, 1);
164 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
);
166 offset
+= SYSV_DIRSIZE
;
167 if (pos
> dir
->i_size
) {
170 mark_inode_dirty(dir
);
173 if (namecompare(namelen
, SYSV_NAMELEN
, name
, de
->name
)) {
178 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME
;
179 mark_inode_dirty(dir
);
180 for (i
= 0; i
< SYSV_NAMELEN
; i
++)
181 de
->name
[i
] = (i
< namelen
) ? name
[i
] : 0;
182 mark_buffer_dirty(bh
, 1);
186 if (offset
< sb
->sv_block_size
)
196 int sysv_create(struct inode
* dir
, struct dentry
* dentry
, int mode
)
199 struct inode
* inode
;
200 struct buffer_head
* bh
;
201 struct sysv_dir_entry
* de
;
203 inode
= sysv_new_inode(dir
);
206 inode
->i_op
= &sysv_file_inode_operations
;
207 inode
->i_mode
= mode
;
208 mark_inode_dirty(inode
);
209 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
210 dentry
->d_name
.len
, &bh
, &de
);
213 mark_inode_dirty(inode
);
217 de
->inode
= inode
->i_ino
;
218 mark_buffer_dirty(bh
, 1);
220 d_instantiate(dentry
, inode
);
224 int sysv_mknod(struct inode
* dir
, struct dentry
* dentry
, int mode
, int rdev
)
227 struct inode
* inode
;
228 struct buffer_head
* bh
;
229 struct sysv_dir_entry
* de
;
231 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
232 dentry
->d_name
.len
, &de
);
237 inode
= sysv_new_inode(dir
);
240 inode
->i_uid
= current
->fsuid
;
241 init_special_inode(inode
, mode
, rdev
);
242 mark_inode_dirty(inode
);
243 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
244 dentry
->d_name
.len
, &bh
, &de
);
247 mark_inode_dirty(inode
);
251 de
->inode
= inode
->i_ino
;
252 mark_buffer_dirty(bh
, 1);
254 d_instantiate(dentry
, inode
);
258 int sysv_mkdir(struct inode
* dir
, struct dentry
*dentry
, int mode
)
261 struct inode
* inode
;
262 struct buffer_head
* bh
, *dir_block
;
263 struct sysv_dir_entry
* de
;
265 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
266 dentry
->d_name
.len
, &de
);
271 if (dir
->i_nlink
>= dir
->i_sb
->sv_link_max
)
273 inode
= sysv_new_inode(dir
);
276 inode
->i_op
= &sysv_dir_inode_operations
;
277 inode
->i_size
= 2 * SYSV_DIRSIZE
;
278 dir_block
= sysv_file_bread(inode
,0,1);
281 mark_inode_dirty(inode
);
285 de
= (struct sysv_dir_entry
*) (dir_block
->b_data
+ 0*SYSV_DIRSIZE
);
286 de
->inode
= inode
->i_ino
;
287 strcpy(de
->name
,"."); /* rest of de->name is zero, see sysv_new_block */
288 de
= (struct sysv_dir_entry
*) (dir_block
->b_data
+ 1*SYSV_DIRSIZE
);
289 de
->inode
= dir
->i_ino
;
290 strcpy(de
->name
,".."); /* rest of de->name is zero, see sysv_new_block */
292 mark_buffer_dirty(dir_block
, 1);
294 inode
->i_mode
= S_IFDIR
| mode
;
295 if (dir
->i_mode
& S_ISGID
)
296 inode
->i_mode
|= S_ISGID
;
297 mark_inode_dirty(inode
);
298 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
299 dentry
->d_name
.len
, &bh
, &de
);
305 de
->inode
= inode
->i_ino
;
306 mark_buffer_dirty(bh
, 1);
308 mark_inode_dirty(dir
);
310 d_instantiate(dentry
, inode
);
315 * routine to check that the specified directory is empty (for rmdir)
317 static int empty_dir(struct inode
* inode
)
319 struct super_block
* sb
;
320 unsigned long pos
, block
, offset
; /* pos = block * block_size + offset */
321 struct buffer_head
* bh
;
322 struct sysv_dir_entry
* de
;
326 pos
= offset
= 2*SYSV_DIRSIZE
;
327 if (inode
->i_size
% SYSV_DIRSIZE
)
329 if (inode
->i_size
< pos
)
331 bh
= sysv_file_bread(inode
, 0, 0);
334 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ 0*SYSV_DIRSIZE
);
335 if (!de
->inode
|| strcmp(de
->name
,"."))
337 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ 1*SYSV_DIRSIZE
);
338 if (!de
->inode
|| strcmp(de
->name
,".."))
341 while (pos
< inode
->i_size
) {
343 bh
= sysv_file_bread(inode
, block
, 0);
345 /* offset = 0; */ block
++;
346 pos
+= sb
->sv_block_size
;
350 de
= (struct sysv_dir_entry
*) (bh
->b_data
+ offset
);
352 offset
+= SYSV_DIRSIZE
;
357 if (offset
< sb
->sv_block_size
)
367 printk("Bad directory on device %s\n",
368 kdevname(inode
->i_dev
));
372 int sysv_rmdir(struct inode
* dir
, struct dentry
* dentry
)
375 struct inode
* inode
;
376 struct buffer_head
* bh
;
377 struct sysv_dir_entry
* de
;
379 inode
= dentry
->d_inode
;
380 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
, &de
);
382 if (!bh
|| de
->inode
!= inode
->i_ino
)
385 if (!empty_dir(inode
)) {
389 if (!list_empty(&dentry
->d_hash
)) {
393 if (inode
->i_nlink
!= 2)
394 printk("empty directory has nlink!=2 (%d)\n", inode
->i_nlink
);
396 mark_buffer_dirty(bh
, 1);
399 inode
->i_ctime
= dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
400 mark_inode_dirty(inode
);
401 mark_inode_dirty(dir
);
409 int sysv_unlink(struct inode
* dir
, struct dentry
* dentry
)
412 struct inode
* inode
;
413 struct buffer_head
* bh
;
414 struct sysv_dir_entry
* de
;
417 inode
= dentry
->d_inode
;
418 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
, &de
);
419 if (!bh
|| de
->inode
!= inode
->i_ino
)
421 if (!inode
->i_nlink
) {
422 printk("Deleting nonexistent file (%s:%lu), %d\n",
423 kdevname(inode
->i_dev
), inode
->i_ino
, inode
->i_nlink
);
427 mark_buffer_dirty(bh
, 1);
428 dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
429 mark_inode_dirty(dir
);
431 inode
->i_ctime
= dir
->i_ctime
;
432 mark_inode_dirty(inode
);
440 int sysv_symlink(struct inode
* dir
, struct dentry
* dentry
,
441 const char * symname
)
443 struct sysv_dir_entry
* de
;
444 struct inode
* inode
;
445 struct buffer_head
* name_block
;
446 char * name_block_data
;
447 struct super_block
* sb
;
450 struct buffer_head
* bh
;
452 if (!(inode
= sysv_new_inode(dir
)))
455 inode
->i_mode
= S_IFLNK
| 0777;
456 inode
->i_op
= &sysv_symlink_inode_operations
;
457 name_block
= sysv_file_bread(inode
, 0, 1);
460 mark_inode_dirty(inode
);
465 name_block_data
= name_block
->b_data
;
467 while (i
< sb
->sv_block_size_1
&& (c
= *(symname
++)))
468 name_block_data
[i
++] = c
;
469 name_block_data
[i
] = 0;
470 mark_buffer_dirty(name_block
, 1);
473 mark_inode_dirty(inode
);
474 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
475 dentry
->d_name
.len
, &de
);
478 mark_inode_dirty(inode
);
483 i
= sysv_add_entry(dir
, dentry
->d_name
.name
,
484 dentry
->d_name
.len
, &bh
, &de
);
487 mark_inode_dirty(inode
);
491 de
->inode
= inode
->i_ino
;
492 mark_buffer_dirty(bh
, 1);
494 d_instantiate(dentry
, inode
);
498 int sysv_link(struct dentry
* old_dentry
, struct inode
* dir
,
499 struct dentry
* dentry
)
501 struct inode
*oldinode
= old_dentry
->d_inode
;
503 struct sysv_dir_entry
* de
;
504 struct buffer_head
* bh
;
506 if (S_ISDIR(oldinode
->i_mode
)) {
509 if (oldinode
->i_nlink
>= oldinode
->i_sb
->sv_link_max
) {
512 bh
= sysv_find_entry(dir
, dentry
->d_name
.name
,
513 dentry
->d_name
.len
, &de
);
518 error
= sysv_add_entry(dir
, dentry
->d_name
.name
,
519 dentry
->d_name
.len
, &bh
, &de
);
524 de
->inode
= oldinode
->i_ino
;
525 mark_buffer_dirty(bh
, 1);
528 oldinode
->i_ctime
= CURRENT_TIME
;
529 mark_inode_dirty(oldinode
);
531 d_instantiate(dentry
, oldinode
);
535 #define PARENT_INO(buffer) \
536 (((struct sysv_dir_entry *) ((buffer) + 1*SYSV_DIRSIZE))->inode)
539 * Anybody can rename anything with this: the permission checks are left to the
540 * higher-level routines.
542 int sysv_rename(struct inode
* old_dir
, struct dentry
* old_dentry
,
543 struct inode
* new_dir
, struct dentry
* new_dentry
)
545 struct inode
* old_inode
, * new_inode
;
546 struct buffer_head
* old_bh
, * new_bh
, * dir_bh
;
547 struct sysv_dir_entry
* old_de
, * new_de
;
550 old_inode
= old_dentry
->d_inode
;
551 new_inode
= new_dentry
->d_inode
;
552 new_bh
= dir_bh
= NULL
;
553 old_bh
= sysv_find_entry(old_dir
, old_dentry
->d_name
.name
,
554 old_dentry
->d_name
.len
, &old_de
);
556 if (!old_bh
|| old_de
->inode
!= old_inode
->i_ino
)
559 new_bh
= sysv_find_entry(new_dir
, new_dentry
->d_name
.name
,
560 new_dentry
->d_name
.len
, &new_de
);
567 if (S_ISDIR(old_inode
->i_mode
)) {
570 if (!empty_dir(new_inode
))
574 dir_bh
= sysv_file_bread(old_inode
, 0, 0);
577 if (PARENT_INO(dir_bh
->b_data
) != old_dir
->i_ino
)
580 if (!new_inode
&& new_dir
!= old_dir
&&
581 new_dir
->i_nlink
>= new_dir
->i_sb
->sv_link_max
)
585 retval
= sysv_add_entry(new_dir
, new_dentry
->d_name
.name
,
586 new_dentry
->d_name
.len
, &new_bh
, &new_de
);
590 new_de
->inode
= old_inode
->i_ino
;
592 old_dir
->i_ctime
= old_dir
->i_mtime
= CURRENT_TIME
;
593 mark_inode_dirty(old_dir
);
594 new_dir
->i_ctime
= new_dir
->i_mtime
= CURRENT_TIME
;
595 mark_inode_dirty(new_dir
);
597 new_inode
->i_nlink
--;
598 new_inode
->i_ctime
= CURRENT_TIME
;
599 mark_inode_dirty(new_inode
);
601 mark_buffer_dirty(old_bh
, 1);
602 mark_buffer_dirty(new_bh
, 1);
604 PARENT_INO(dir_bh
->b_data
) = new_dir
->i_ino
;
605 mark_buffer_dirty(dir_bh
, 1);
607 mark_inode_dirty(old_dir
);
609 new_inode
->i_nlink
--;
610 mark_inode_dirty(new_inode
);
613 mark_inode_dirty(new_dir
);