diff options
Diffstat (limited to 'fs/nfs/nfs3proc.c')
| -rw-r--r-- | fs/nfs/nfs3proc.c | 76 |
1 files changed, 32 insertions, 44 deletions
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 828945d68342..3878494dfc2c 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -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; } |
