[PATCH 17/18] nfsd: use vfs_lookup_open() for non-creating open requests too.
NeilBrown <[email protected]>
| Newsgroups | gmane.linux.nfs,gmane.linux.file-systems |
|---|---|
| Message-ID | <[email protected]> |
From: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> Now that we use vfs_lookup_open() for creating open requests, we can use for non-creating too as vfs_lookup_open() is already able to do that. This means that when exporting NFS, the lookup and open can be combined using ->atomic_open. The resulting simplification allows fh_fill_pre_attrs() to be moved into nfsd4_open_file() (renamed from nfsd4_create_file()) so it is closer to fh_full_post_attrs and fh_fill_post_noop calls. As ->op_create_mode isn't defined when op_create is zero, we need a local create_mode which is -1 (illegal value) when op_create is zero. Signed-off-by: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> --- fs/nfsd/nfs4proc.c | 97 +++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 61ecd4123817..19a2d3446ae3 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -201,30 +201,30 @@ static inline bool nfsd4_create_is_exclusive(int createmode) createmode == NFS4_CREATE_EXCLUSIVE4_1; } - /* - * Implement NFSv4's unchecked, guarded, and exclusive create - * semantics for regular files. Open state for this new file is - * subsequently fabricated in nfsd4_process_open2(). - * + * Implement NFSv4's open semantics for regular files. + * Both create (unchecked, guarded, and exclusive) and non-create. + * Open state for this new file is subsequently fabricated in + * nfsd4_process_open2(). * Upon return, caller must release @fhp and @resfhp. */ static __be32 -nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct svc_fh *resfhp, struct nfsd4_open *open) +nfsd4_open_file(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct svc_fh *resfhp, struct nfsd4_open *open) { struct iattr *iap = &open->op_iattr; struct nfsd_attrs attrs = { .na_iattr = iap, .na_seclabel = &open->op_label, }; - int oflags = O_CREAT | O_LARGEFILE; + int oflags = O_LARGEFILE; struct dentry *child = ERR_PTR(-EINVAL); struct path parent = { .mnt = fhp->fh_export->ex_path.mnt, .dentry = fhp->fh_dentry, }; __u32 v_mtime, v_atime; + int createmode = -1; __be32 status; if (isdotent(open->op_fname, open->op_fnamelen)) @@ -236,6 +236,10 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, if (status != nfs_ok) return status; + status = fh_fill_pre_attrs(fhp); + if (status) + return status; + if (!IS_POSIXACL(d_inode(parent.dentry))) iap->ia_mode &= ~current_umask(); @@ -258,13 +262,18 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, open->op_pacl = NULL; } + if (open->op_create) { + createmode = open->op_createmode; + oflags |= O_CREAT; + } + /* A newly created file already has a file size of zero. */ if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0)) iap->ia_valid &= ~ATTR_SIZE; v_mtime = 0; v_atime = 0; - if (nfsd4_create_is_exclusive(open->op_createmode)) { + if (nfsd4_create_is_exclusive(createmode)) { u32 *verifier = (u32 *)open->op_verf.data; /* @@ -288,7 +297,7 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, /* Only ask the fs to provide exclusive-create if we aren't using * the NFS verifier to do it outselves. */ - if (open->op_createmode == NFS4_CREATE_GUARDED) + if (createmode == NFS4_CREATE_GUARDED) oflags |= O_EXCL; switch (open->op_share_access & NFS4_SHARE_ACCESS_BOTH) { @@ -321,14 +330,14 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; if (!open->op_created && - nfsd4_create_is_exclusive(open->op_createmode) && + nfsd4_create_is_exclusive(createmode) && inode_get_mtime_sec(d_inode(child)) == v_mtime && inode_get_atime_sec(d_inode(child)) == v_atime && d_inode(child)->i_size == 0) open->op_created = true; if (!open->op_created && - open->op_createmode == NFS4_CREATE_UNCHECKED) { + createmode == NFS4_CREATE_UNCHECKED) { /* NFSv4 protocol requires change attributes * even though no change happened. */ @@ -429,45 +438,35 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru fh_init(*resfh, NFS4_FHSIZE); open->op_truncate = false; - status = fh_fill_pre_attrs(current_fh); - if (status) - goto out; - if (open->op_create) { - /* FIXME: check session persistence and pnfs flags. - * The nfsv4.1 spec requires the following semantics: - * - * Persistent | pNFS | Server REQUIRED | Client Allowed - * Reply Cache | server | | - * -------------+--------+-----------------+-------------------- - * no | no | EXCLUSIVE4_1 | EXCLUSIVE4_1 - * | | | (SHOULD) - * | | and EXCLUSIVE4 | or EXCLUSIVE4 - * | | | (SHOULD NOT) - * no | yes | EXCLUSIVE4_1 | EXCLUSIVE4_1 - * yes | no | GUARDED4 | GUARDED4 - * yes | yes | GUARDED4 | GUARDED4 - */ + /* FIXME: check session persistence and pnfs flags. + * The nfsv4.1 spec requires the following semantics: + * + * Persistent | pNFS | Server REQUIRED | Client Allowed + * Reply Cache | server | | + * -------------+--------+-----------------+-------------------- + * no | no | EXCLUSIVE4_1 | EXCLUSIVE4_1 + * | | | (SHOULD) + * | | and EXCLUSIVE4 | or EXCLUSIVE4 + * | | | (SHOULD NOT) + * no | yes | EXCLUSIVE4_1 | EXCLUSIVE4_1 + * yes | no | GUARDED4 | GUARDED4 + * yes | yes | GUARDED4 | GUARDED4 + */ - current->fs->umask = open->op_umask; - status = nfsd4_create_file(rqstp, current_fh, *resfh, open); - current->fs->umask = 0; + current->fs->umask = open->op_umask; + status = nfsd4_open_file(rqstp, current_fh, *resfh, open); + current->fs->umask = 0; + + /* + * Following rfc 3530 14.2.16, and rfc 5661 18.16.4 + * use the returned bitmask to indicate which attributes + * we used to store the verifier: + */ + if (open->op_create && status == 0 && + nfsd4_create_is_exclusive(open->op_createmode)) + open->op_bmval[1] |= (FATTR4_WORD1_TIME_ACCESS | + FATTR4_WORD1_TIME_MODIFY); - /* - * Following rfc 3530 14.2.16, and rfc 5661 18.16.4 - * use the returned bitmask to indicate which attributes - * we used to store the verifier: - */ - if (nfsd4_create_is_exclusive(open->op_createmode) && status == 0) - open->op_bmval[1] |= (FATTR4_WORD1_TIME_ACCESS | - FATTR4_WORD1_TIME_MODIFY); - } else { - status = nfsd_lookup(rqstp, current_fh, - open->op_fname, open->op_fnamelen, *resfh); - /* NFSv4 protocol requires change attributes even though - * no change happened. - */ - fh_fill_post_noop(current_fh); - } if (status) goto out; status = nfsd_check_obj_isreg(*resfh, cstate->minorversion); -- 2.50.0.107.gf914562f5916.dirty