Skip to content

Commit 5f46e95

Browse files
committed
NFSD: Refactor nfsd_create_setattr()
I'd like to move do_nfsd_create() out of vfs.c. Therefore nfsd_create_setattr() needs to be made publicly visible. Note that both call sites in vfs.c commit both the new object and its parent directory, so just combine those common metadata commits into nfsd_create_setattr(). Signed-off-by: Chuck Lever <[email protected]>
1 parent 14ee45b commit 5f46e95

File tree

2 files changed

+44
-37
lines changed

2 files changed

+44
-37
lines changed

fs/nfsd/vfs.c

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,25 +1181,58 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset,
11811181
return err;
11821182
}
11831183

1184-
static __be32
1185-
nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
1186-
struct iattr *iap)
1184+
/**
1185+
* nfsd_create_setattr - Set a created file's attributes
1186+
* @rqstp: RPC transaction being executed
1187+
* @fhp: NFS filehandle of parent directory
1188+
* @resfhp: NFS filehandle of new object
1189+
* @iap: requested attributes of new object
1190+
*
1191+
* Returns nfs_ok on success, or an nfsstat in network byte order.
1192+
*/
1193+
__be32
1194+
nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
1195+
struct svc_fh *resfhp, struct iattr *iap)
11871196
{
1197+
__be32 status;
1198+
11881199
/*
1189-
* Mode has already been set earlier in create:
1200+
* Mode has already been set by file creation.
11901201
*/
11911202
iap->ia_valid &= ~ATTR_MODE;
1203+
11921204
/*
11931205
* Setting uid/gid works only for root. Irix appears to
11941206
* send along the gid on create when it tries to implement
11951207
* setgid directories via NFS:
11961208
*/
11971209
if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
11981210
iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
1211+
1212+
/*
1213+
* Callers expect new file metadata to be committed even
1214+
* if the attributes have not changed.
1215+
*/
11991216
if (iap->ia_valid)
1200-
return nfsd_setattr(rqstp, resfhp, iap, 0, (time64_t)0);
1201-
/* Callers expect file metadata to be committed here */
1202-
return nfserrno(commit_metadata(resfhp));
1217+
status = nfsd_setattr(rqstp, resfhp, iap, 0, (time64_t)0);
1218+
else
1219+
status = nfserrno(commit_metadata(resfhp));
1220+
1221+
/*
1222+
* Transactional filesystems had a chance to commit changes
1223+
* for both parent and child simultaneously making the
1224+
* following commit_metadata a noop in many cases.
1225+
*/
1226+
if (!status)
1227+
status = nfserrno(commit_metadata(fhp));
1228+
1229+
/*
1230+
* Update the new filehandle to pick up the new attributes.
1231+
*/
1232+
if (!status)
1233+
status = fh_update(resfhp);
1234+
1235+
return status;
12031236
}
12041237

12051238
/* HPUX client sometimes creates a file in mode 000, and sets size to 0.
@@ -1226,7 +1259,6 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
12261259
struct dentry *dentry, *dchild;
12271260
struct inode *dirp;
12281261
__be32 err;
1229-
__be32 err2;
12301262
int host_err;
12311263

12321264
dentry = fhp->fh_dentry;
@@ -1299,22 +1331,8 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
12991331
if (host_err < 0)
13001332
goto out_nfserr;
13011333

1302-
err = nfsd_create_setattr(rqstp, resfhp, iap);
1334+
err = nfsd_create_setattr(rqstp, fhp, resfhp, iap);
13031335

1304-
/*
1305-
* nfsd_create_setattr already committed the child. Transactional
1306-
* filesystems had a chance to commit changes for both parent and
1307-
* child simultaneously making the following commit_metadata a
1308-
* noop.
1309-
*/
1310-
err2 = nfserrno(commit_metadata(fhp));
1311-
if (err2)
1312-
err = err2;
1313-
/*
1314-
* Update the file handle to get the new inode info.
1315-
*/
1316-
if (!err)
1317-
err = fh_update(resfhp);
13181336
out:
13191337
dput(dchild);
13201338
return err;
@@ -1505,20 +1523,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
15051523
}
15061524

15071525
set_attr:
1508-
err = nfsd_create_setattr(rqstp, resfhp, iap);
1509-
1510-
/*
1511-
* nfsd_create_setattr already committed the child
1512-
* (and possibly also the parent).
1513-
*/
1514-
if (!err)
1515-
err = nfserrno(commit_metadata(fhp));
1516-
1517-
/*
1518-
* Update the filehandle to get the new inode info.
1519-
*/
1520-
if (!err)
1521-
err = fh_update(resfhp);
1526+
err = nfsd_create_setattr(rqstp, fhp, resfhp, iap);
15221527

15231528
out:
15241529
fh_unlock(fhp);

fs/nfsd/vfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
6969
char *name, int len, struct iattr *attrs,
7070
int type, dev_t rdev, struct svc_fh *res);
7171
__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
72+
__be32 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
73+
struct svc_fh *resfhp, struct iattr *iap);
7274
__be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *,
7375
char *name, int len, struct iattr *attrs,
7476
struct svc_fh *res, int createmode,

0 commit comments

Comments
 (0)