Skip to content

Commit

Permalink
nfsd: have nfsd4_deleg_getattr_conflict pass back write deleg pointer
Browse files Browse the repository at this point in the history
Currently we pass back the size and whether it has been modified, but
those just mirror values tracked inside the delegation. In a later
patch, we'll need to get at the timestamps in the delegation too, so
just pass back a reference to the write delegation, and use that to
properly override values in the iattr.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
  • Loading branch information
Jeff Layton authored and Chuck Lever committed Nov 11, 2024
1 parent 3a40543 commit f6259e2
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 16 deletions.
17 changes: 8 additions & 9 deletions fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -8863,8 +8863,7 @@ nfsd4_get_writestateid(struct nfsd4_compound_state *cstate,
* nfsd4_deleg_getattr_conflict - Recall if GETATTR causes conflict
* @rqstp: RPC transaction context
* @dentry: dentry of inode to be checked for a conflict
* @modified: return true if file was modified
* @size: new size of file if modified is true
* @pdp: returned WRITE delegation, if one was found
*
* This function is called when there is a conflict between a write
* delegation and a change/size GETATTR from another client. The server
Expand All @@ -8874,11 +8873,12 @@ nfsd4_get_writestateid(struct nfsd4_compound_state *cstate,
* 18.7.4.
*
* Returns 0 if there is no conflict; otherwise an nfs_stat
* code is returned.
* code is returned. If @pdp is set to a non-NULL value, then the
* caller must put the reference.
*/
__be32
nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
bool *modified, u64 *size)
struct nfs4_delegation **pdp)
{
__be32 status;
struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
Expand All @@ -8889,10 +8889,9 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
struct nfs4_cb_fattr *ncf;
struct inode *inode = d_inode(dentry);

*modified = false;
ctx = locks_inode_context(inode);
if (!ctx)
return 0;
return nfs_ok;

#define NON_NFSD_LEASE ((void *)1)

Expand Down Expand Up @@ -8958,10 +8957,10 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
goto out_status;
}
ncf->ncf_cur_fsize = ncf->ncf_cb_fsize;
*size = ncf->ncf_cur_fsize;
*modified = true;
*pdp = dp;
return nfs_ok;
}
status = 0;
status = nfs_ok;
out_status:
nfs4_put_stid(&dp->dl_stid);
return status;
Expand Down
16 changes: 10 additions & 6 deletions fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3511,6 +3511,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
int ignore_crossmnt)
{
DECLARE_BITMAP(attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops));
struct nfs4_delegation *dp = NULL;
struct nfsd4_fattr_args args;
struct svc_fh *tempfh = NULL;
int starting_len = xdr->buf->len;
Expand All @@ -3525,8 +3526,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
.dentry = dentry,
};
unsigned long bit;
bool file_modified = false;
u64 size = 0;

WARN_ON_ONCE(bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1);
WARN_ON_ONCE(!nfsd_attrs_supported(minorversion, bmval));
Expand Down Expand Up @@ -3555,19 +3554,24 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
goto out;
}
if (attrmask[0] & (FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE)) {
status = nfsd4_deleg_getattr_conflict(rqstp, dentry,
&file_modified, &size);
status = nfsd4_deleg_getattr_conflict(rqstp, dentry, &dp);
if (status)
goto out;
}

err = vfs_getattr(&path, &args.stat,
STATX_BASIC_STATS | STATX_BTIME | STATX_CHANGE_COOKIE,
AT_STATX_SYNC_AS_STAT);
if (dp) {
struct nfs4_cb_fattr *ncf = &dp->dl_cb_fattr;

if (ncf->ncf_file_modified)
args.stat.size = ncf->ncf_cur_fsize;

nfs4_put_stid(&dp->dl_stid);
}
if (err)
goto out_nfserr;
if (file_modified)
args.stat.size = size;

if (!(args.stat.result_mask & STATX_BTIME))
/* underlying FS does not offer btime so we can't share it */
Expand Down
2 changes: 1 addition & 1 deletion fs/nfsd/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -783,5 +783,5 @@ static inline bool try_to_expire_client(struct nfs4_client *clp)
}

extern __be32 nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,
struct dentry *dentry, bool *file_modified, u64 *size);
struct dentry *dentry, struct nfs4_delegation **pdp);
#endif /* NFSD4_STATE_H */

0 comments on commit f6259e2

Please sign in to comment.