Create a nameidata2 struct in nfsd and mqueue so that vfs_create does
need to conditionally pass the vfsmnt.

Signed-off-by: Andreas Gruenbacher <[EMAIL PROTECTED]>

---
 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
@@ -603,9 +603,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)))
@@ -618,7 +623,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-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to