4 * Copyright (c) 1999 Al Smith
6 * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
9 #include <linux/string.h>
10 #include <linux/efs_fs.h>
12 static efs_ino_t
efs_find_entry(struct inode
*inode
, const char *name
, int len
) {
13 struct buffer_head
*bh
;
17 struct efs_dir
*dirblock
;
18 struct efs_dentry
*dirslot
;
22 if (inode
->i_size
& (EFS_DIRBSIZE
-1))
23 printk(KERN_WARNING
"EFS: WARNING: find_entry(): directory size not a multiple of EFS_DIRBSIZE\n");
25 for(block
= 0; block
< inode
->i_blocks
; block
++) {
27 bh
= bread(inode
->i_dev
, efs_bmap(inode
, block
), EFS_DIRBSIZE
);
29 printk(KERN_ERR
"EFS: find_entry(): failed to read dir block %d\n", block
);
33 dirblock
= (struct efs_dir
*) bh
->b_data
;
35 if (be16_to_cpu(dirblock
->magic
) != EFS_DIRBLK_MAGIC
) {
36 printk(KERN_ERR
"EFS: find_entry(): invalid directory block\n");
41 for(slot
= 0; slot
< dirblock
->slots
; slot
++) {
42 dirslot
= (struct efs_dentry
*) (((char *) bh
->b_data
) + EFS_SLOTAT(dirblock
, slot
));
44 namelen
= dirslot
->namelen
;
45 nameptr
= dirslot
->name
;
47 if ((namelen
== len
) && (!memcmp(name
, nameptr
, len
))) {
48 inodenum
= be32_to_cpu(dirslot
->inode
);
58 struct dentry
*efs_lookup(struct inode
*dir
, struct dentry
*dentry
) {
62 if (!dir
|| !S_ISDIR(dir
->i_mode
))
63 return ERR_PTR(-ENOENT
);
67 inodenum
= efs_find_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
);
69 if (!(inode
= iget(dir
->i_sb
, inodenum
)))
70 return ERR_PTR(-EACCES
);