Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jeff Layton and committed by
Chuck Lever
f6259e2e 3a405432

+19 -16
+8 -9
fs/nfsd/nfs4state.c
··· 8863 8863 * nfsd4_deleg_getattr_conflict - Recall if GETATTR causes conflict 8864 8864 * @rqstp: RPC transaction context 8865 8865 * @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 8868 8867 * 8869 8868 * This function is called when there is a conflict between a write 8870 8869 * delegation and a change/size GETATTR from another client. The server ··· 8873 8874 * 18.7.4. 8874 8875 * 8875 8876 * Returns 0 if there is no conflict; otherwise an nfs_stat 8876 - * code is returned. 8877 + * code is returned. If @pdp is set to a non-NULL value, then the 8878 + * caller must put the reference. 8877 8879 */ 8878 8880 __be32 8879 8881 nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry, 8880 - bool *modified, u64 *size) 8882 + struct nfs4_delegation **pdp) 8881 8883 { 8882 8884 __be32 status; 8883 8885 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); ··· 8889 8889 struct nfs4_cb_fattr *ncf; 8890 8890 struct inode *inode = d_inode(dentry); 8891 8891 8892 - *modified = false; 8893 8892 ctx = locks_inode_context(inode); 8894 8893 if (!ctx) 8895 - return 0; 8894 + return nfs_ok; 8896 8895 8897 8896 #define NON_NFSD_LEASE ((void *)1) 8898 8897 ··· 8957 8958 goto out_status; 8958 8959 } 8959 8960 ncf->ncf_cur_fsize = ncf->ncf_cb_fsize; 8960 - *size = ncf->ncf_cur_fsize; 8961 - *modified = true; 8961 + *pdp = dp; 8962 + return nfs_ok; 8962 8963 } 8963 - status = 0; 8964 + status = nfs_ok; 8964 8965 out_status: 8965 8966 nfs4_put_stid(&dp->dl_stid); 8966 8967 return status;
+10 -6
fs/nfsd/nfs4xdr.c
··· 3511 3511 int ignore_crossmnt) 3512 3512 { 3513 3513 DECLARE_BITMAP(attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)); 3514 + struct nfs4_delegation *dp = NULL; 3514 3515 struct nfsd4_fattr_args args; 3515 3516 struct svc_fh *tempfh = NULL; 3516 3517 int starting_len = xdr->buf->len; ··· 3526 3525 .dentry = dentry, 3527 3526 }; 3528 3527 unsigned long bit; 3529 - bool file_modified = false; 3530 - u64 size = 0; 3531 3528 3532 3529 WARN_ON_ONCE(bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1); 3533 3530 WARN_ON_ONCE(!nfsd_attrs_supported(minorversion, bmval)); ··· 3554 3555 goto out; 3555 3556 } 3556 3557 if (attrmask[0] & (FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE)) { 3557 - status = nfsd4_deleg_getattr_conflict(rqstp, dentry, 3558 - &file_modified, &size); 3558 + status = nfsd4_deleg_getattr_conflict(rqstp, dentry, &dp); 3559 3559 if (status) 3560 3560 goto out; 3561 3561 } ··· 3562 3564 err = vfs_getattr(&path, &args.stat, 3563 3565 STATX_BASIC_STATS | STATX_BTIME | STATX_CHANGE_COOKIE, 3564 3566 AT_STATX_SYNC_AS_STAT); 3567 + if (dp) { 3568 + struct nfs4_cb_fattr *ncf = &dp->dl_cb_fattr; 3569 + 3570 + if (ncf->ncf_file_modified) 3571 + args.stat.size = ncf->ncf_cur_fsize; 3572 + 3573 + nfs4_put_stid(&dp->dl_stid); 3574 + } 3565 3575 if (err) 3566 3576 goto out_nfserr; 3567 - if (file_modified) 3568 - args.stat.size = size; 3569 3577 3570 3578 if (!(args.stat.result_mask & STATX_BTIME)) 3571 3579 /* underlying FS does not offer btime so we can't share it */
+1 -1
fs/nfsd/state.h
··· 783 783 } 784 784 785 785 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); 787 787 #endif /* NFSD4_STATE_H */