vserver 2.0 rc7
[linux-2.6.git] / fs / nfs / nfs3proc.c
index 828945d..3878494 100644 (file)
@@ -295,7 +295,7 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
  * Create a regular file.
  * For now, we don't implement O_EXCL.
  */
-static struct inode *
+static int
 nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                 int flags)
 {
@@ -342,29 +342,19 @@ again:
                                break;
 
                        case NFS3_CREATE_UNCHECKED:
-                               goto exit;
+                               goto out;
                }
                goto again;
        }
 
-exit:
-       dprintk("NFS reply create: %d\n", status);
-
+       if (status == 0)
+               status = nfs_instantiate(dentry, &fhandle, &fattr);
        if (status != 0)
                goto out;
-       if (fhandle.size == 0 || !(fattr.valid & NFS_ATTR_FATTR)) {
-               status = nfs3_proc_lookup(dir, &dentry->d_name, &fhandle, &fattr);
-               if (status != 0)
-                       goto out;
-       }
 
        /* When we created the file with exclusive semantics, make
         * sure we set the attributes afterwards. */
        if (arg.createmode == NFS3_CREATE_EXCLUSIVE) {
-               struct nfs3_sattrargs   arg = {
-                       .fh             = &fhandle,
-                       .sattr          = sattr,
-               };
                dprintk("NFS call  setattr (post-create)\n");
 
                if (!(sattr->ia_valid & ATTR_ATIME_SET))
@@ -375,20 +365,13 @@ exit:
                /* Note: we could use a guarded setattr here, but I'm
                 * not sure this buys us anything (and I'd have
                 * to revamp the NFSv3 XDR code) */
-               fattr.valid = 0;
-               status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SETATTR,
-                                               &arg, &fattr, 0);
+               status = nfs3_proc_setattr(dentry, &fattr, sattr);
+               nfs_refresh_inode(dentry->d_inode, &fattr);
                dprintk("NFS reply setattr (post-create): %d\n", status);
        }
-       if (status == 0) {
-               struct inode *inode;
-               inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
-               if (inode)
-                       return inode;
-               status = -ENOMEM;
-       }
 out:
-       return ERR_PTR(status);
+       dprintk("NFS reply create: %d\n", status);
+       return status;
 }
 
 static int
@@ -540,28 +523,30 @@ nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
 }
 
 static int
-nfs3_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
-               struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
 {
-       struct nfs_fattr        dir_attr;
+       struct nfs_fh fhandle;
+       struct nfs_fattr fattr, dir_attr;
        struct nfs3_mkdirargs   arg = {
                .fh             = NFS_FH(dir),
-               .name           = name->name,
-               .len            = name->len,
+               .name           = dentry->d_name.name,
+               .len            = dentry->d_name.len,
                .sattr          = sattr
        };
        struct nfs3_diropres    res = {
                .dir_attr       = &dir_attr,
-               .fh             = fhandle,
-               .fattr          = fattr
+               .fh             = &fhandle,
+               .fattr          = &fattr
        };
        int                     status;
 
-       dprintk("NFS call  mkdir %s\n", name->name);
+       dprintk("NFS call  mkdir %s\n", dentry->d_name.name);
        dir_attr.valid = 0;
-       fattr->valid = 0;
+       fattr.valid = 0;
        status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
        nfs_refresh_inode(dir, &dir_attr);
+       if (status == 0)
+               status = nfs_instantiate(dentry, &fhandle, &fattr);
        dprintk("NFS reply mkdir: %d\n", status);
        return status;
 }
@@ -639,23 +624,24 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 }
 
 static int
-nfs3_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
-               dev_t rdev, struct nfs_fh *fh, struct nfs_fattr *fattr)
+nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+               dev_t rdev)
 {
-       struct nfs_fattr        dir_attr;
+       struct nfs_fh fh;
+       struct nfs_fattr fattr, dir_attr;
        struct nfs3_mknodargs   arg = {
                .fh             = NFS_FH(dir),
-               .name           = name->name,
-               .len            = name->len,
+               .name           = dentry->d_name.name,
+               .len            = dentry->d_name.len,
                .sattr          = sattr,
                .rdev           = rdev
        };
        struct nfs3_diropres    res = {
                .dir_attr       = &dir_attr,
-               .fh             = fh,
-               .fattr          = fattr
+               .fh             = &fh,
+               .fattr          = &fattr
        };
-       int                     status;
+       int status;
 
        switch (sattr->ia_mode & S_IFMT) {
        case S_IFBLK:   arg.type = NF3BLK;  break;
@@ -665,12 +651,14 @@ nfs3_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
        default:        return -EINVAL;
        }
 
-       dprintk("NFS call  mknod %s %u:%u\n", name->name,
+       dprintk("NFS call  mknod %s %u:%u\n", dentry->d_name.name,
                        MAJOR(rdev), MINOR(rdev));
        dir_attr.valid = 0;
-       fattr->valid = 0;
+       fattr.valid = 0;
        status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
        nfs_refresh_inode(dir, &dir_attr);
+       if (status == 0)
+               status = nfs_instantiate(dentry, &fh, &fattr);
        dprintk("NFS reply mknod: %d\n", status);
        return status;
 }