From: Erez Zadok Date: Sat, 30 Apr 2011 05:33:58 +0000 (-0400) Subject: VFS: introduce lookup_one_len_nd X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=311117c07b4183291b9ccb7dea67394fc4e8291f;p=unionfs-3.8.y.git VFS: introduce lookup_one_len_nd Just like lookup_one_len() but passes a nameidata parameter, which is now required by NFS3, else you get an oops. Signed-off-by: Erez Zadok --- diff --git a/fs/namei.c b/fs/namei.c index ec97aef5c21..d6f3fb0d619 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2142,6 +2142,42 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) return __lookup_hash(&this, base, 0); } +/* pass nameidata from caller (useful for NFS) */ +struct dentry *lookup_one_len_nd(const char *name, struct dentry *base, + int len, struct nameidata *nd) +{ + struct qstr this; + unsigned long hash; + unsigned int c; + + WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex)); + + this.name = name; + this.len = len; + if (!len) + return ERR_PTR(-EACCES); + + hash = init_name_hash(); + while (len--) { + c = *(const unsigned char *)name++; + if (c == '/' || c == '\0') + return ERR_PTR(-EACCES); + hash = partial_name_hash(c, hash); + } + this.hash = end_name_hash(hash); + /* + * See if the low-level filesystem might want + * to use its own hash.. + */ + if (base->d_flags & DCACHE_OP_HASH) { + int err = base->d_op->d_hash(base, base->d_inode, &this); + if (err < 0) + return ERR_PTR(err); + } + + return __lookup_hash(&this, base, nd); +} + int user_path_at_empty(int dfd, const char __user *name, unsigned flags, struct path *path, int *empty) { @@ -4085,6 +4121,7 @@ EXPORT_SYMBOL(follow_up); EXPORT_SYMBOL(get_write_access); /* nfsd */ EXPORT_SYMBOL(lock_rename); EXPORT_SYMBOL(lookup_one_len); +EXPORT_SYMBOL(lookup_one_len_nd); EXPORT_SYMBOL(page_follow_link_light); EXPORT_SYMBOL(page_put_link); EXPORT_SYMBOL(page_readlink); diff --git a/include/linux/namei.h b/include/linux/namei.h index 5a5ff57ceed..0c4c26cbaf6 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -74,6 +74,8 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *); extern struct dentry *lookup_one_len(const char *, struct dentry *, int); +extern struct dentry *lookup_one_len_nd(const char *, struct dentry *, int, + struct nameidata *nd); extern int follow_down_one(struct path *); extern int follow_down(struct path *);