* 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)
{
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))
/* 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
}
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;
}
}
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;
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;
}