mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
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 <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
3a405432e7
commit
f6259e2e4f
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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));
|
||||
|
|
@ -3555,8 +3554,7 @@ 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;
|
||||
}
|
||||
|
|
@ -3564,10 +3562,16 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
|
|||
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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user