diff options
Diffstat (limited to 'fs/efs/namei.c')
| -rw-r--r-- | fs/efs/namei.c | 104 |
1 files changed, 40 insertions, 64 deletions
diff --git a/fs/efs/namei.c b/fs/efs/namei.c index 5276b19423c..356c044e2cd 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c @@ -8,8 +8,9 @@ #include <linux/buffer_head.h> #include <linux/string.h> -#include <linux/efs_fs.h> -#include <linux/smp_lock.h> +#include <linux/exportfs.h> +#include "efs.h" + static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { struct buffer_head *bh; @@ -22,20 +23,22 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) 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\n"); + pr_warn("%s(): directory size not a multiple of EFS_DIRBSIZE\n", + __func__); 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\n", block); + pr_err("%s(): failed to read dir block %d\n", + __func__, 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\n"); + pr_err("%s(): invalid directory block\n", __func__); brelse(bh); return(0); } @@ -57,86 +60,59 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) return(0); } -struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { +struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) +{ efs_ino_t inodenum; - struct inode * inode = NULL; + 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(); + if (inodenum) + inode = efs_iget(dir->i_sb, inodenum); - d_add(dentry, inode); - return NULL; + return d_splice_alias(inode, dentry); } -struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp) +static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino, + u32 generation) { - __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; - } + inode = efs_iget(sb, ino); + if (IS_ERR(inode)) + return ERR_CAST(inode); - result = d_alloc_anon(inode); - if (!result) { - result = ERR_PTR(-ENOMEM); - goto out_iput; + if (generation && inode->i_generation != generation) { + iput(inode); + return ERR_PTR(-ESTALE); } - return result; - out_iput: - iput(inode); - return result; + return inode; +} + +struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + return generic_fh_to_dentry(sb, fid, fh_len, fh_type, + efs_nfs_get_inode); +} + +struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + return generic_fh_to_parent(sb, fid, fh_len, fh_type, + efs_nfs_get_inode); } struct dentry *efs_get_parent(struct dentry *child) { - struct dentry *parent; - struct inode *inode; + struct dentry *parent = ERR_PTR(-ENOENT); 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; + if (ino) + parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino)); - 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); } |
