Create a nameidata2 struct in nfsd and mqueue so that vfs_create does need to conditionally pass the vfsmnt. Signed-off-by: Andreas Gruenbacher Signed-off-by: John Johansen --- fs/namei.c | 2 +- fs/nfsd/vfs.c | 42 +++++++++++++++++++++++++----------------- ipc/mqueue.c | 7 ++++++- 3 files changed, 32 insertions(+), 19 deletions(-) --- a/fs/namei.c +++ b/fs/namei.c @@ -1532,7 +1532,7 @@ int vfs_create(struct inode *dir, struct return -EACCES; /* shouldn't it be ENOSYS? */ mode &= S_IALLUGO; mode |= S_IFREG; - error = security_inode_create(dir, dentry, nd ? nd->mnt : NULL, mode); + error = security_inode_create(dir, dentry, nd->mnt, mode); if (error) return error; DQUOT_INIT(dir); --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1121,7 +1121,8 @@ nfsd_create(struct svc_rqst *rqstp, stru char *fname, int flen, struct iattr *iap, int type, dev_t rdev, struct svc_fh *resfhp) { - struct dentry *dentry, *dchild = NULL; + struct nameidata2 nd; + struct dentry *dchild = NULL; struct svc_export *exp; struct inode *dirp; __be32 err; @@ -1138,9 +1139,11 @@ nfsd_create(struct svc_rqst *rqstp, stru if (err) goto out; - dentry = fhp->fh_dentry; + nd.dentry = fhp->fh_dentry; exp = fhp->fh_export; - dirp = dentry->d_inode; + nd.mnt = exp->ex_mnt; + nd.flags = 0; + dirp = nd.dentry->d_inode; err = nfserr_notdir; if(!dirp->i_op || !dirp->i_op->lookup) @@ -1152,7 +1155,7 @@ nfsd_create(struct svc_rqst *rqstp, stru if (!resfhp->fh_dentry) { /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ fh_lock_nested(fhp, I_MUTEX_PARENT); - dchild = lookup_one_len(fname, dentry, flen); + dchild = lookup_one_len(fname, nd.dentry, flen); host_err = PTR_ERR(dchild); if (IS_ERR(dchild)) goto out_nfserr; @@ -1166,8 +1169,8 @@ nfsd_create(struct svc_rqst *rqstp, stru /* not actually possible */ printk(KERN_ERR "nfsd_create: parent %s/%s not locked!\n", - dentry->d_parent->d_name.name, - dentry->d_name.name); + nd.dentry->d_parent->d_name.name, + nd.dentry->d_name.name); err = nfserr_io; goto out; } @@ -1178,7 +1181,7 @@ nfsd_create(struct svc_rqst *rqstp, stru err = nfserr_exist; if (dchild->d_inode) { dprintk("nfsd_create: dentry %s/%s not negative!\n", - dentry->d_name.name, dchild->d_name.name); + nd.dentry->d_name.name, dchild->d_name.name); goto out; } @@ -1192,7 +1195,7 @@ nfsd_create(struct svc_rqst *rqstp, stru err = 0; switch (type) { case S_IFREG: - host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); + host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd); break; case S_IFDIR: host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode); @@ -1212,7 +1215,7 @@ nfsd_create(struct svc_rqst *rqstp, stru goto out_nfserr; if (EX_ISSYNC(exp)) { - err = nfserrno(nfsd_sync_dir(dentry)); + err = nfserrno(nfsd_sync_dir(nd.dentry)); write_inode_now(dchild->d_inode, 1); } @@ -1252,7 +1255,9 @@ nfsd_create_v3(struct svc_rqst *rqstp, s struct svc_fh *resfhp, int createmode, u32 *verifier, int *truncp, int *created) { - struct dentry *dentry, *dchild = NULL; + struct nameidata2 nd; + struct dentry *dchild = NULL; + struct svc_export *exp; struct inode *dirp; __be32 err; int host_err; @@ -1270,8 +1275,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, s if (err) goto out; - dentry = fhp->fh_dentry; - dirp = dentry->d_inode; + nd.dentry = fhp->fh_dentry; + exp = fhp->fh_export; + nd.mnt = exp->ex_mnt; + nd.flags = 0; + dirp = nd.dentry->d_inode; /* Get all the sanity checks out of the way before * we lock the parent. */ @@ -1283,12 +1291,12 @@ nfsd_create_v3(struct svc_rqst *rqstp, s /* * Compose the response file handle. */ - dchild = lookup_one_len(fname, dentry, flen); + dchild = lookup_one_len(fname, nd.dentry, flen); host_err = PTR_ERR(dchild); if (IS_ERR(dchild)) goto out_nfserr; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); + err = fh_compose(resfhp, exp, dchild, fhp); if (err) goto out; @@ -1334,14 +1342,14 @@ nfsd_create_v3(struct svc_rqst *rqstp, s goto out; } - host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); + host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd); if (host_err < 0) goto out_nfserr; if (created) *created = 1; - if (EX_ISSYNC(fhp->fh_export)) { - err = nfserrno(nfsd_sync_dir(dentry)); + if (EX_ISSYNC(exp)) { + err = nfserrno(nfsd_sync_dir(nd.dentry)); /* setattr will sync the child (or not) */ } --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -602,9 +602,14 @@ static int mq_attr_ok(struct mq_attr *at static struct file *do_create(struct dentry *dir, struct dentry *dentry, int oflag, mode_t mode, struct mq_attr __user *u_attr) { + struct nameidata2 nd; struct mq_attr attr; int ret; + nd.dentry = dir; + nd.mnt = NULL; /* Not a mounted filesystem */ + nd.flags = 0; + if (u_attr) { ret = -EFAULT; if (copy_from_user(&attr, u_attr, sizeof(attr))) @@ -617,7 +622,7 @@ static struct file *do_create(struct den } mode &= ~current->fs->umask; - ret = vfs_create(dir->d_inode, dentry, mode, NULL); + ret = vfs_create(dir->d_inode, dentry, mode, &nd); dentry->d_fsdata = NULL; if (ret) goto out; -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/