Skip to content

Commit f6259e2

Browse files
jtlaytonchucklever
authored andcommitted
nfsd: have nfsd4_deleg_getattr_conflict pass back write deleg pointer
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 <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 3a40543 commit f6259e2

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

fs/nfsd/nfs4state.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8863,8 +8863,7 @@ nfsd4_get_writestateid(struct nfsd4_compound_state *cstate,
88638863
* nfsd4_deleg_getattr_conflict - Recall if GETATTR causes conflict
88648864
* @rqstp: RPC transaction context
88658865
* @dentry: dentry of inode to be checked for a conflict
8866-
* @modified: return true if file was modified
8867-
* @size: new size of file if modified is true
8866+
* @pdp: returned WRITE delegation, if one was found
88688867
*
88698868
* This function is called when there is a conflict between a write
88708869
* delegation and a change/size GETATTR from another client. The server
@@ -8874,11 +8873,12 @@ nfsd4_get_writestateid(struct nfsd4_compound_state *cstate,
88748873
* 18.7.4.
88758874
*
88768875
* Returns 0 if there is no conflict; otherwise an nfs_stat
8877-
* code is returned.
8876+
* code is returned. If @pdp is set to a non-NULL value, then the
8877+
* caller must put the reference.
88788878
*/
88798879
__be32
88808880
nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
8881-
bool *modified, u64 *size)
8881+
struct nfs4_delegation **pdp)
88828882
{
88838883
__be32 status;
88848884
struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
@@ -8889,10 +8889,9 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
88898889
struct nfs4_cb_fattr *ncf;
88908890
struct inode *inode = d_inode(dentry);
88918891

8892-
*modified = false;
88938892
ctx = locks_inode_context(inode);
88948893
if (!ctx)
8895-
return 0;
8894+
return nfs_ok;
88968895

88978896
#define NON_NFSD_LEASE ((void *)1)
88988897

@@ -8958,10 +8957,10 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
89588957
goto out_status;
89598958
}
89608959
ncf->ncf_cur_fsize = ncf->ncf_cb_fsize;
8961-
*size = ncf->ncf_cur_fsize;
8962-
*modified = true;
8960+
*pdp = dp;
8961+
return nfs_ok;
89638962
}
8964-
status = 0;
8963+
status = nfs_ok;
89658964
out_status:
89668965
nfs4_put_stid(&dp->dl_stid);
89678966
return status;

fs/nfsd/nfs4xdr.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3511,6 +3511,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
35113511
int ignore_crossmnt)
35123512
{
35133513
DECLARE_BITMAP(attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops));
3514+
struct nfs4_delegation *dp = NULL;
35143515
struct nfsd4_fattr_args args;
35153516
struct svc_fh *tempfh = NULL;
35163517
int starting_len = xdr->buf->len;
@@ -3525,8 +3526,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
35253526
.dentry = dentry,
35263527
};
35273528
unsigned long bit;
3528-
bool file_modified = false;
3529-
u64 size = 0;
35303529

35313530
WARN_ON_ONCE(bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1);
35323531
WARN_ON_ONCE(!nfsd_attrs_supported(minorversion, bmval));
@@ -3555,19 +3554,24 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
35553554
goto out;
35563555
}
35573556
if (attrmask[0] & (FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE)) {
3558-
status = nfsd4_deleg_getattr_conflict(rqstp, dentry,
3559-
&file_modified, &size);
3557+
status = nfsd4_deleg_getattr_conflict(rqstp, dentry, &dp);
35603558
if (status)
35613559
goto out;
35623560
}
35633561

35643562
err = vfs_getattr(&path, &args.stat,
35653563
STATX_BASIC_STATS | STATX_BTIME | STATX_CHANGE_COOKIE,
35663564
AT_STATX_SYNC_AS_STAT);
3565+
if (dp) {
3566+
struct nfs4_cb_fattr *ncf = &dp->dl_cb_fattr;
3567+
3568+
if (ncf->ncf_file_modified)
3569+
args.stat.size = ncf->ncf_cur_fsize;
3570+
3571+
nfs4_put_stid(&dp->dl_stid);
3572+
}
35673573
if (err)
35683574
goto out_nfserr;
3569-
if (file_modified)
3570-
args.stat.size = size;
35713575

35723576
if (!(args.stat.result_mask & STATX_BTIME))
35733577
/* underlying FS does not offer btime so we can't share it */

fs/nfsd/state.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,5 +783,5 @@ static inline bool try_to_expire_client(struct nfs4_client *clp)
783783
}
784784

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

0 commit comments

Comments
 (0)