Blame view
fs/efs/namei.c
2.91 KB
1da177e4c
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/* * namei.c * * Copyright (c) 1999 Al Smith * * Portions derived from work (c) 1995,1996 Christian Vogelgsang. */ #include <linux/buffer_head.h> #include <linux/string.h> #include <linux/efs_fs.h> #include <linux/smp_lock.h> static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { struct buffer_head *bh; int slot, namelen; char *nameptr; struct efs_dir *dirblock; struct efs_dentry *dirslot; efs_ino_t inodenum; efs_block_t block; if (inode->i_size & (EFS_DIRBSIZE-1)) printk(KERN_WARNING "EFS: WARNING: find_entry(): directory size not a multiple of EFS_DIRBSIZE "); for(block = 0; block < inode->i_blocks; block++) { bh = sb_bread(inode->i_sb, efs_bmap(inode, block)); if (!bh) { printk(KERN_ERR "EFS: find_entry(): failed to read dir block %d ", block); return 0; } dirblock = (struct efs_dir *) bh->b_data; if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) { printk(KERN_ERR "EFS: find_entry(): invalid directory block "); brelse(bh); return(0); } for(slot = 0; slot < dirblock->slots; slot++) { dirslot = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot)); namelen = dirslot->namelen; nameptr = dirslot->name; if ((namelen == len) && (!memcmp(name, nameptr, len))) { inodenum = be32_to_cpu(dirslot->inode); brelse(bh); return(inodenum); } } brelse(bh); } return(0); } struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { efs_ino_t inodenum; struct inode * inode = NULL; lock_kernel(); inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); if (inodenum) { if (!(inode = iget(dir->i_sb, inodenum))) { unlock_kernel(); return ERR_PTR(-EACCES); } } unlock_kernel(); d_add(dentry, inode); return NULL; } |
5ca296073
|
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp) { __u32 *objp = vobjp; unsigned long ino = objp[0]; __u32 generation = objp[1]; struct inode *inode; struct dentry *result; if (ino == 0) return ERR_PTR(-ESTALE); inode = iget(sb, ino); if (inode == NULL) return ERR_PTR(-ENOMEM); if (is_bad_inode(inode) || (generation && inode->i_generation != generation)) { result = ERR_PTR(-ESTALE); goto out_iput; } result = d_alloc_anon(inode); if (!result) { result = ERR_PTR(-ENOMEM); goto out_iput; } return result; out_iput: iput(inode); return result; } |
1da177e4c
|
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
struct dentry *efs_get_parent(struct dentry *child) { struct dentry *parent; struct inode *inode; efs_ino_t ino; int error; lock_kernel(); error = -ENOENT; ino = efs_find_entry(child->d_inode, "..", 2); if (!ino) goto fail; error = -EACCES; inode = iget(child->d_inode->i_sb, ino); if (!inode) goto fail; error = -ENOMEM; parent = d_alloc_anon(inode); if (!parent) goto fail_iput; unlock_kernel(); return parent; fail_iput: iput(inode); fail: unlock_kernel(); return ERR_PTR(error); } |