4 * Copyright (c) 1999 Al Smith
6 * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
9 #include <linux/buffer_head.h>
10 #include <linux/string.h>
11 #include <linux/efs_fs.h>
12 #include <linux/smp_lock.h>
14 static efs_ino_t
efs_find_entry(struct inode
*inode
, const char *name
, int len
) {
15 struct buffer_head
*bh
;
19 struct efs_dir
*dirblock
;
20 struct efs_dentry
*dirslot
;
24 if (inode
->i_size
& (EFS_DIRBSIZE
-1))
25 printk(KERN_WARNING
"EFS: WARNING: find_entry(): directory size not a multiple of EFS_DIRBSIZE\n");
27 for(block
= 0; block
< inode
->i_blocks
; block
++) {
29 bh
= sb_bread(inode
->i_sb
, efs_bmap(inode
, block
));
31 printk(KERN_ERR
"EFS: find_entry(): failed to read dir block %d\n", block
);
35 dirblock
= (struct efs_dir
*) bh
->b_data
;
37 if (be16_to_cpu(dirblock
->magic
) != EFS_DIRBLK_MAGIC
) {
38 printk(KERN_ERR
"EFS: find_entry(): invalid directory block\n");
43 for(slot
= 0; slot
< dirblock
->slots
; slot
++) {
44 dirslot
= (struct efs_dentry
*) (((char *) bh
->b_data
) + EFS_SLOTAT(dirblock
, slot
));
46 namelen
= dirslot
->namelen
;
47 nameptr
= dirslot
->name
;
49 if ((namelen
== len
) && (!memcmp(name
, nameptr
, len
))) {
50 inodenum
= be32_to_cpu(dirslot
->inode
);
60 struct dentry
*efs_lookup(struct inode
*dir
, struct dentry
*dentry
, struct nameidata
*nd
) {
62 struct inode
* inode
= NULL
;
65 inodenum
= efs_find_entry(dir
, dentry
->d_name
.name
, dentry
->d_name
.len
);
67 if (!(inode
= iget(dir
->i_sb
, inodenum
))) {
69 return ERR_PTR(-EACCES
);
78 struct dentry
*efs_get_parent(struct dentry
*child
)
80 struct dentry
*parent
;
88 ino
= efs_find_entry(child
->d_inode
, "..", 2);
93 inode
= iget(child
->d_inode
->i_sb
, ino
);
98 parent
= d_alloc_anon(inode
);
109 return ERR_PTR(error
);