2 * linux/fs/minix/namei.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/sched.h>
8 #include <linux/minix_fs.h>
9 #include <linux/kernel.h>
10 #include <linux/string.h>
11 #include <linux/stat.h>
12 #include <linux/fcntl.h>
13 #include <linux/errno.h>
15 #include <asm/uaccess.h>
18 * comment out this line if you want names > info->s_namelen chars to be
19 * truncated. Else they will be disallowed (ENAMETOOLONG).
21 /* #define NO_TRUNCATE */
23 static inline int namecompare(int len
, int maxlen
,
24 const char * name
, const char * buffer
)
26 if (len
< maxlen
&& buffer
[len
])
28 return !memcmp(name
, buffer
, len
);
34 * finds an entry in the specified directory with the wanted name. It
35 * returns the cache buffer in which the entry was found, and the entry
36 * itself (as a parameter - res_dir). It does NOT read the inode of the
37 * entry - you'll have to do that yourself if you want to.
39 static struct buffer_head
* minix_find_entry(struct inode
* dir
,
40 const char * name
, int namelen
, struct minix_dir_entry
** res_dir
)
42 unsigned long block
, offset
;
43 struct buffer_head
* bh
;
44 struct minix_sb_info
* info
;
45 struct minix_dir_entry
*de
;
48 info
= &dir
->i_sb
->u
.minix_sb
;
49 if (namelen
> info
->s_namelen
) {
53 namelen
= info
->s_namelen
;
58 while (block
*BLOCK_SIZE
+offset
< dir
->i_size
) {
60 bh
= minix_bread(dir
,block
,0);
66 de
= (struct minix_dir_entry
*) (bh
->b_data
+ offset
);
67 offset
+= info
->s_dirsize
;
68 if (de
->inode
&& namecompare(namelen
,info
->s_namelen
,name
,de
->name
)) {
72 if (offset
< bh
->b_size
)
85 static int minix_hash(struct dentry
*dentry
, struct qstr
*qstr
)
89 const unsigned char *name
;
91 i
= dentry
->d_inode
->i_sb
->u
.minix_sb
.s_namelen
;
94 /* Truncate the name in place, avoids having to define a compare
98 hash
= init_name_hash();
100 hash
= partial_name_hash(*name
++, hash
);
101 qstr
->hash
= end_name_hash(hash
);
107 struct dentry_operations minix_dentry_operations
= {
117 struct dentry
*minix_lookup(struct inode
* dir
, struct dentry
*dentry
)
119 struct inode
* inode
= NULL
;
120 struct minix_dir_entry
* de
;
121 struct buffer_head
* bh
;
124 dentry
->d_op
= &minix_dentry_operations
;
126 bh
= minix_find_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
, &de
);
130 inode
= iget(dir
->i_sb
, ino
);
133 return ERR_PTR(-EACCES
);
135 d_add(dentry
, inode
);
142 * adds a file entry to the specified directory, returning a possible
143 * error value if it fails.
145 * NOTE!! The inode part of 'de' is left at 0 - which means you
146 * may not sleep between calling this and putting something into
147 * the entry, as someone else might have used it while you slept.
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
)
155 unsigned long block
, offset
;
156 struct buffer_head
* bh
;
157 struct minix_dir_entry
* de
;
158 struct minix_sb_info
* info
;
162 info
= &dir
->i_sb
->u
.minix_sb
;
163 if (namelen
> info
->s_namelen
) {
165 return -ENAMETOOLONG
;
167 namelen
= info
->s_namelen
;
176 bh
= minix_bread(dir
,block
,1);
180 de
= (struct minix_dir_entry
*) (bh
->b_data
+ offset
);
181 offset
+= info
->s_dirsize
;
182 if (block
*bh
->b_size
+ offset
> dir
->i_size
) {
184 dir
->i_size
= block
*bh
->b_size
+ offset
;
185 mark_inode_dirty(dir
);
188 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME
;
189 mark_inode_dirty(dir
);
190 for (i
= 0; i
< info
->s_namelen
; i
++)
191 de
->name
[i
] = (i
< namelen
) ? name
[i
] : 0;
192 dir
->i_version
= ++event
;
193 mark_buffer_dirty(bh
, 1);
197 if (offset
< bh
->b_size
)
208 int minix_create(struct inode
* dir
, struct dentry
*dentry
, int mode
)
211 struct inode
* inode
;
212 struct buffer_head
* bh
;
213 struct minix_dir_entry
* de
;
215 inode
= minix_new_inode(dir
);
218 inode
->i_op
= &minix_file_inode_operations
;
219 inode
->i_mode
= mode
;
220 mark_inode_dirty(inode
);
221 error
= minix_add_entry(dir
, dentry
->d_name
.name
,
222 dentry
->d_name
.len
, &bh
,&de
);
225 mark_inode_dirty(inode
);
229 de
->inode
= inode
->i_ino
;
230 mark_buffer_dirty(bh
, 1);
232 d_instantiate(dentry
, inode
);
236 int minix_mknod(struct inode
* dir
, struct dentry
*dentry
, int mode
, int rdev
)
239 struct inode
* inode
;
240 struct buffer_head
* bh
;
241 struct minix_dir_entry
* de
;
243 inode
= minix_new_inode(dir
);
246 inode
->i_uid
= current
->fsuid
;
247 init_special_inode(inode
, mode
, rdev
);
248 mark_inode_dirty(inode
);
249 error
= minix_add_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
, &bh
, &de
);
252 mark_inode_dirty(inode
);
256 de
->inode
= inode
->i_ino
;
257 mark_buffer_dirty(bh
, 1);
259 d_instantiate(dentry
, inode
);
263 int minix_mkdir(struct inode
* dir
, struct dentry
*dentry
, int mode
)
266 struct inode
* inode
;
267 struct buffer_head
* bh
, *dir_block
;
268 struct minix_dir_entry
* de
;
269 struct minix_sb_info
* info
;
271 info
= &dir
->i_sb
->u
.minix_sb
;
272 if (dir
->i_nlink
>= info
->s_link_max
)
274 inode
= minix_new_inode(dir
);
277 inode
->i_op
= &minix_dir_inode_operations
;
278 inode
->i_size
= 2 * info
->s_dirsize
;
279 dir_block
= minix_bread(inode
,0,1);
282 mark_inode_dirty(inode
);
286 de
= (struct minix_dir_entry
*) dir_block
->b_data
;
287 de
->inode
=inode
->i_ino
;
288 strcpy(de
->name
,".");
289 de
= (struct minix_dir_entry
*) (dir_block
->b_data
+ info
->s_dirsize
);
290 de
->inode
= dir
->i_ino
;
291 strcpy(de
->name
,"..");
293 mark_buffer_dirty(dir_block
, 1);
295 inode
->i_mode
= S_IFDIR
| mode
;
296 if (dir
->i_mode
& S_ISGID
)
297 inode
->i_mode
|= S_ISGID
;
298 mark_inode_dirty(inode
);
299 error
= minix_add_entry(dir
, dentry
->d_name
.name
,
300 dentry
->d_name
.len
, &bh
, &de
);
306 de
->inode
= inode
->i_ino
;
307 mark_buffer_dirty(bh
, 1);
309 mark_inode_dirty(dir
);
311 d_instantiate(dentry
, inode
);
316 * routine to check that the specified directory is empty (for rmdir)
318 static int empty_dir(struct inode
* inode
)
320 unsigned int block
, offset
;
321 struct buffer_head
* bh
;
322 struct minix_dir_entry
* de
;
323 struct minix_sb_info
* info
;
325 info
= &inode
->i_sb
->u
.minix_sb
;
328 offset
= 2*info
->s_dirsize
;
329 if (inode
->i_size
& (info
->s_dirsize
-1))
331 if (inode
->i_size
< offset
)
333 bh
= minix_bread(inode
,0,0);
336 de
= (struct minix_dir_entry
*) bh
->b_data
;
337 if (!de
->inode
|| strcmp(de
->name
,"."))
339 de
= (struct minix_dir_entry
*) (bh
->b_data
+ info
->s_dirsize
);
340 if (!de
->inode
|| strcmp(de
->name
,".."))
342 while (block
*BLOCK_SIZE
+offset
< inode
->i_size
) {
344 bh
= minix_bread(inode
,block
,0);
350 de
= (struct minix_dir_entry
*) (bh
->b_data
+ offset
);
351 offset
+= info
->s_dirsize
;
356 if (offset
< bh
->b_size
)
367 printk("Bad directory on device %s\n",
368 kdevname(inode
->i_dev
));
372 int minix_rmdir(struct inode
* dir
, struct dentry
*dentry
)
375 struct inode
* inode
;
376 struct buffer_head
* bh
;
377 struct minix_dir_entry
* de
;
380 bh
= minix_find_entry(dir
, dentry
->d_name
.name
,
381 dentry
->d_name
.len
, &de
);
385 inode
= dentry
->d_inode
;
387 if (!empty_dir(inode
)) {
391 if (de
->inode
!= inode
->i_ino
) {
395 if (!list_empty(&dentry
->d_hash
)) {
399 if (inode
->i_nlink
!= 2)
400 printk("empty directory has nlink!=2 (%d)\n",inode
->i_nlink
);
402 dir
->i_version
= ++event
;
403 mark_buffer_dirty(bh
, 1);
405 mark_inode_dirty(inode
);
406 inode
->i_ctime
= dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
408 mark_inode_dirty(dir
);
416 int minix_unlink(struct inode
* dir
, struct dentry
*dentry
)
419 struct inode
* inode
;
420 struct buffer_head
* bh
;
421 struct minix_dir_entry
* de
;
424 inode
= dentry
->d_inode
;
425 bh
= minix_find_entry(dir
, dentry
->d_name
.name
,
426 dentry
->d_name
.len
, &de
);
427 if (!bh
|| de
->inode
!= inode
->i_ino
)
429 if (!inode
->i_nlink
) {
430 printk("Deleting nonexistent file (%s:%lu), %d\n",
431 kdevname(inode
->i_dev
),
432 inode
->i_ino
, inode
->i_nlink
);
436 dir
->i_version
= ++event
;
437 mark_buffer_dirty(bh
, 1);
438 dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
439 mark_inode_dirty(dir
);
441 inode
->i_ctime
= dir
->i_ctime
;
442 mark_inode_dirty(inode
);
443 d_delete(dentry
); /* This also frees the inode */
450 int minix_symlink(struct inode
* dir
, struct dentry
*dentry
,
451 const char * symname
)
453 struct minix_dir_entry
* de
;
454 struct inode
* inode
= NULL
;
455 struct buffer_head
* bh
= NULL
, * name_block
= NULL
;
459 if (!(inode
= minix_new_inode(dir
)))
462 inode
->i_mode
= S_IFLNK
| 0777;
463 inode
->i_op
= &minix_symlink_inode_operations
;
464 name_block
= minix_bread(inode
,0,1);
467 mark_inode_dirty(inode
);
472 while (i
< 1023 && (c
=*(symname
++)))
473 name_block
->b_data
[i
++] = c
;
474 name_block
->b_data
[i
] = 0;
475 mark_buffer_dirty(name_block
, 1);
478 mark_inode_dirty(inode
);
479 i
= minix_add_entry(dir
, dentry
->d_name
.name
,
480 dentry
->d_name
.len
, &bh
, &de
);
483 mark_inode_dirty(inode
);
487 de
->inode
= inode
->i_ino
;
488 mark_buffer_dirty(bh
, 1);
490 d_instantiate(dentry
, inode
);
494 int minix_link(struct dentry
* old_dentry
, struct inode
* dir
,
495 struct dentry
*dentry
)
498 struct inode
*inode
= old_dentry
->d_inode
;
499 struct minix_dir_entry
* de
;
500 struct buffer_head
* bh
;
502 if (S_ISDIR(inode
->i_mode
))
505 if (inode
->i_nlink
>= inode
->i_sb
->u
.minix_sb
.s_link_max
)
508 error
= minix_add_entry(dir
, dentry
->d_name
.name
,
509 dentry
->d_name
.len
, &bh
, &de
);
514 de
->inode
= inode
->i_ino
;
515 mark_buffer_dirty(bh
, 1);
518 inode
->i_ctime
= CURRENT_TIME
;
519 mark_inode_dirty(inode
);
521 d_instantiate(dentry
, inode
);
525 #define PARENT_INO(buffer) \
526 (((struct minix_dir_entry *) ((buffer)+info->s_dirsize))->inode)
529 * Anybody can rename anything with this: the permission checks are left to the
530 * higher-level routines.
532 int minix_rename(struct inode
* old_dir
, struct dentry
*old_dentry
,
533 struct inode
* new_dir
, struct dentry
*new_dentry
)
535 struct inode
* old_inode
, * new_inode
;
536 struct buffer_head
* old_bh
, * new_bh
, * dir_bh
;
537 struct minix_dir_entry
* old_de
, * new_de
;
538 struct minix_sb_info
* info
;
541 info
= &old_dir
->i_sb
->u
.minix_sb
;
542 new_bh
= dir_bh
= NULL
;
543 old_inode
= old_dentry
->d_inode
;
544 new_inode
= new_dentry
->d_inode
;
545 old_bh
= minix_find_entry(old_dir
, old_dentry
->d_name
.name
,
546 old_dentry
->d_name
.len
, &old_de
);
548 if (!old_bh
|| old_de
->inode
!= old_inode
->i_ino
)
551 new_bh
= minix_find_entry(new_dir
, new_dentry
->d_name
.name
,
552 new_dentry
->d_name
.len
, &new_de
);
559 if (S_ISDIR(old_inode
->i_mode
)) {
562 if (!empty_dir(new_inode
))
566 dir_bh
= minix_bread(old_inode
,0,0);
569 if (PARENT_INO(dir_bh
->b_data
) != old_dir
->i_ino
)
572 if (!new_inode
&& new_dir
!= old_dir
&&
573 new_dir
->i_nlink
>= info
->s_link_max
)
577 retval
= minix_add_entry(new_dir
,
578 new_dentry
->d_name
.name
,
579 new_dentry
->d_name
.len
,
585 new_de
->inode
= old_inode
->i_ino
;
587 old_dir
->i_ctime
= old_dir
->i_mtime
= CURRENT_TIME
;
588 old_dir
->i_version
= ++event
;
589 mark_inode_dirty(old_dir
);
590 new_dir
->i_ctime
= new_dir
->i_mtime
= CURRENT_TIME
;
591 new_dir
->i_version
= ++event
;
592 mark_inode_dirty(new_dir
);
594 new_inode
->i_nlink
--;
595 new_inode
->i_ctime
= CURRENT_TIME
;
596 mark_inode_dirty(new_inode
);
598 mark_buffer_dirty(old_bh
, 1);
599 mark_buffer_dirty(new_bh
, 1);
601 PARENT_INO(dir_bh
->b_data
) = new_dir
->i_ino
;
602 mark_buffer_dirty(dir_bh
, 1);
604 mark_inode_dirty(old_dir
);
606 new_inode
->i_nlink
--;
607 mark_inode_dirty(new_inode
);
610 mark_inode_dirty(new_dir
);