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.sunysb.edu/?a=commitdiff_plain;h=f24ff824e5f0a5b3da836b101db9542b0b2299f6;p=unionfs-2.6.39.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 bbfd1e00355..40fe90fbbde 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1825,6 +1825,42 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) return __lookup_hash(&this, base, NULL); } +/* 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(int dfd, const char __user *name, unsigned flags, struct path *path) { @@ -3428,6 +3464,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ EXPORT_SYMBOL(getname); 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 1a35f3fdd81..8e19e9c69ab 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -84,6 +84,8 @@ extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry extern void release_open_intent(struct nameidata *); 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 *);