@@ -8834,6 +8834,7 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
8834
8834
__be32 status ;
8835
8835
struct nfsd_net * nn = net_generic (SVC_NET (rqstp ), nfsd_net_id );
8836
8836
struct file_lock_context * ctx ;
8837
+ struct nfs4_delegation * dp = NULL ;
8837
8838
struct file_lease * fl ;
8838
8839
struct iattr attrs ;
8839
8840
struct nfs4_cb_fattr * ncf ;
@@ -8843,84 +8844,76 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
8843
8844
ctx = locks_inode_context (inode );
8844
8845
if (!ctx )
8845
8846
return 0 ;
8847
+
8848
+ #define NON_NFSD_LEASE ((void *)1)
8849
+
8846
8850
spin_lock (& ctx -> flc_lock );
8847
8851
for_each_file_lock (fl , & ctx -> flc_lease ) {
8848
- unsigned char type = fl -> c .flc_type ;
8849
-
8850
8852
if (fl -> c .flc_flags == FL_LAYOUT )
8851
8853
continue ;
8852
- if (fl -> fl_lmops != & nfsd_lease_mng_ops ) {
8853
- /*
8854
- * non-nfs lease, if it's a lease with F_RDLCK then
8855
- * we are done; there isn't any write delegation
8856
- * on this inode
8857
- */
8858
- if (type == F_RDLCK )
8859
- break ;
8860
-
8861
- nfsd_stats_wdeleg_getattr_inc (nn );
8862
- spin_unlock (& ctx -> flc_lock );
8863
-
8864
- status = nfserrno (nfsd_open_break_lease (inode , NFSD_MAY_READ ));
8854
+ if (fl -> c .flc_type == F_WRLCK ) {
8855
+ if (fl -> fl_lmops == & nfsd_lease_mng_ops )
8856
+ dp = fl -> c .flc_owner ;
8857
+ else
8858
+ dp = NON_NFSD_LEASE ;
8859
+ }
8860
+ break ;
8861
+ }
8862
+ if (dp == NULL || dp == NON_NFSD_LEASE ||
8863
+ dp -> dl_recall .cb_clp == * (rqstp -> rq_lease_breaker )) {
8864
+ spin_unlock (& ctx -> flc_lock );
8865
+ if (dp == NON_NFSD_LEASE ) {
8866
+ status = nfserrno (nfsd_open_break_lease (inode ,
8867
+ NFSD_MAY_READ ));
8865
8868
if (status != nfserr_jukebox ||
8866
8869
!nfsd_wait_for_delegreturn (rqstp , inode ))
8867
8870
return status ;
8868
- return 0 ;
8869
8871
}
8870
- if ( type == F_WRLCK ) {
8871
- struct nfs4_delegation * dp = fl -> c . flc_owner ;
8872
+ return 0 ;
8873
+ }
8872
8874
8873
- if (dp -> dl_recall .cb_clp == * (rqstp -> rq_lease_breaker )) {
8874
- spin_unlock (& ctx -> flc_lock );
8875
- return 0 ;
8876
- }
8877
- nfsd_stats_wdeleg_getattr_inc (nn );
8878
- dp = fl -> c .flc_owner ;
8879
- refcount_inc (& dp -> dl_stid .sc_count );
8880
- ncf = & dp -> dl_cb_fattr ;
8881
- nfs4_cb_getattr (& dp -> dl_cb_fattr );
8882
- spin_unlock (& ctx -> flc_lock );
8883
- wait_on_bit_timeout (& ncf -> ncf_cb_flags , CB_GETATTR_BUSY ,
8884
- TASK_INTERRUPTIBLE , NFSD_CB_GETATTR_TIMEOUT );
8885
- if (ncf -> ncf_cb_status ) {
8886
- /* Recall delegation only if client didn't respond */
8887
- status = nfserrno (nfsd_open_break_lease (inode , NFSD_MAY_READ ));
8888
- if (status != nfserr_jukebox ||
8889
- !nfsd_wait_for_delegreturn (rqstp , inode )) {
8890
- nfs4_put_stid (& dp -> dl_stid );
8891
- return status ;
8892
- }
8893
- }
8894
- if (!ncf -> ncf_file_modified &&
8895
- (ncf -> ncf_initial_cinfo != ncf -> ncf_cb_change ||
8896
- ncf -> ncf_cur_fsize != ncf -> ncf_cb_fsize ))
8897
- ncf -> ncf_file_modified = true;
8898
- if (ncf -> ncf_file_modified ) {
8899
- int err ;
8900
-
8901
- /*
8902
- * Per section 10.4.3 of RFC 8881, the server would
8903
- * not update the file's metadata with the client's
8904
- * modified size
8905
- */
8906
- attrs .ia_mtime = attrs .ia_ctime = current_time (inode );
8907
- attrs .ia_valid = ATTR_MTIME | ATTR_CTIME | ATTR_DELEG ;
8908
- inode_lock (inode );
8909
- err = notify_change (& nop_mnt_idmap , dentry , & attrs , NULL );
8910
- inode_unlock (inode );
8911
- if (err ) {
8912
- nfs4_put_stid (& dp -> dl_stid );
8913
- return nfserrno (err );
8914
- }
8915
- ncf -> ncf_cur_fsize = ncf -> ncf_cb_fsize ;
8916
- * size = ncf -> ncf_cur_fsize ;
8917
- * modified = true;
8918
- }
8919
- nfs4_put_stid (& dp -> dl_stid );
8920
- return 0 ;
8875
+ nfsd_stats_wdeleg_getattr_inc (nn );
8876
+ refcount_inc (& dp -> dl_stid .sc_count );
8877
+ ncf = & dp -> dl_cb_fattr ;
8878
+ nfs4_cb_getattr (& dp -> dl_cb_fattr );
8879
+ spin_unlock (& ctx -> flc_lock );
8880
+
8881
+ wait_on_bit_timeout (& ncf -> ncf_cb_flags , CB_GETATTR_BUSY ,
8882
+ TASK_INTERRUPTIBLE , NFSD_CB_GETATTR_TIMEOUT );
8883
+ if (ncf -> ncf_cb_status ) {
8884
+ /* Recall delegation only if client didn't respond */
8885
+ status = nfserrno (nfsd_open_break_lease (inode , NFSD_MAY_READ ));
8886
+ if (status != nfserr_jukebox ||
8887
+ !nfsd_wait_for_delegreturn (rqstp , inode ))
8888
+ goto out_status ;
8889
+ }
8890
+ if (!ncf -> ncf_file_modified &&
8891
+ (ncf -> ncf_initial_cinfo != ncf -> ncf_cb_change ||
8892
+ ncf -> ncf_cur_fsize != ncf -> ncf_cb_fsize ))
8893
+ ncf -> ncf_file_modified = true;
8894
+ if (ncf -> ncf_file_modified ) {
8895
+ int err ;
8896
+
8897
+ /*
8898
+ * Per section 10.4.3 of RFC 8881, the server would
8899
+ * not update the file's metadata with the client's
8900
+ * modified size
8901
+ */
8902
+ attrs .ia_mtime = attrs .ia_ctime = current_time (inode );
8903
+ attrs .ia_valid = ATTR_MTIME | ATTR_CTIME | ATTR_DELEG ;
8904
+ inode_lock (inode );
8905
+ err = notify_change (& nop_mnt_idmap , dentry , & attrs , NULL );
8906
+ inode_unlock (inode );
8907
+ if (err ) {
8908
+ status = nfserrno (err );
8909
+ goto out_status ;
8921
8910
}
8922
- break ;
8911
+ ncf -> ncf_cur_fsize = ncf -> ncf_cb_fsize ;
8912
+ * size = ncf -> ncf_cur_fsize ;
8913
+ * modified = true;
8923
8914
}
8924
- spin_unlock (& ctx -> flc_lock );
8925
- return 0 ;
8915
+ status = 0 ;
8916
+ out_status :
8917
+ nfs4_put_stid (& dp -> dl_stid );
8918
+ return status ;
8926
8919
}
0 commit comments