@@ -2789,15 +2789,18 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
27892789 deny & NFS4_SHARE_ACCESS_READ ? "r" : "-" ,
27902790 deny & NFS4_SHARE_ACCESS_WRITE ? "w" : "-" );
27912791
2792- spin_lock (& nf -> fi_lock );
2793- file = find_any_file_locked (nf );
2794- if (file ) {
2795- nfs4_show_superblock (s , file );
2796- seq_puts (s , ", " );
2797- nfs4_show_fname (s , file );
2798- seq_puts (s , ", " );
2799- }
2800- spin_unlock (& nf -> fi_lock );
2792+ if (nf ) {
2793+ spin_lock (& nf -> fi_lock );
2794+ file = find_any_file_locked (nf );
2795+ if (file ) {
2796+ nfs4_show_superblock (s , file );
2797+ seq_puts (s , ", " );
2798+ nfs4_show_fname (s , file );
2799+ seq_puts (s , ", " );
2800+ }
2801+ spin_unlock (& nf -> fi_lock );
2802+ } else
2803+ seq_puts (s , "closed, " );
28012804 nfs4_show_owner (s , oo );
28022805 if (st -> sc_status & SC_STATUS_ADMIN_REVOKED )
28032806 seq_puts (s , ", admin-revoked" );
@@ -3075,9 +3078,9 @@ nfsd4_cb_getattr_release(struct nfsd4_callback *cb)
30753078 struct nfs4_delegation * dp =
30763079 container_of (ncf , struct nfs4_delegation , dl_cb_fattr );
30773080
3078- nfs4_put_stid (& dp -> dl_stid );
30793081 clear_bit (CB_GETATTR_BUSY , & ncf -> ncf_cb_flags );
30803082 wake_up_bit (& ncf -> ncf_cb_flags , CB_GETATTR_BUSY );
3083+ nfs4_put_stid (& dp -> dl_stid );
30813084}
30823085
30833086static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops = {
@@ -8812,7 +8815,7 @@ nfsd4_get_writestateid(struct nfsd4_compound_state *cstate,
88128815/**
88138816 * nfsd4_deleg_getattr_conflict - Recall if GETATTR causes conflict
88148817 * @rqstp: RPC transaction context
8815- * @inode: file to be checked for a conflict
8818+ * @dentry: dentry of inode to be checked for a conflict
88168819 * @modified: return true if file was modified
88178820 * @size: new size of file if modified is true
88188821 *
@@ -8827,16 +8830,16 @@ nfsd4_get_writestateid(struct nfsd4_compound_state *cstate,
88278830 * code is returned.
88288831 */
88298832__be32
8830- nfsd4_deleg_getattr_conflict (struct svc_rqst * rqstp , struct inode * inode ,
8833+ nfsd4_deleg_getattr_conflict (struct svc_rqst * rqstp , struct dentry * dentry ,
88318834 bool * modified , u64 * size )
88328835{
88338836 __be32 status ;
88348837 struct nfsd_net * nn = net_generic (SVC_NET (rqstp ), nfsd_net_id );
88358838 struct file_lock_context * ctx ;
88368839 struct file_lease * fl ;
8837- struct nfs4_delegation * dp ;
88388840 struct iattr attrs ;
88398841 struct nfs4_cb_fattr * ncf ;
8842+ struct inode * inode = d_inode (dentry );
88408843
88418844 * modified = false;
88428845 ctx = locks_inode_context (inode );
@@ -8859,14 +8862,16 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode,
88598862 goto break_lease ;
88608863 }
88618864 if (type == F_WRLCK ) {
8862- dp = fl -> c .flc_owner ;
8865+ struct nfs4_delegation * dp = fl -> c .flc_owner ;
8866+
88638867 if (dp -> dl_recall .cb_clp == * (rqstp -> rq_lease_breaker )) {
88648868 spin_unlock (& ctx -> flc_lock );
88658869 return 0 ;
88668870 }
88678871break_lease :
88688872 nfsd_stats_wdeleg_getattr_inc (nn );
88698873 dp = fl -> c .flc_owner ;
8874+ refcount_inc (& dp -> dl_stid .sc_count );
88708875 ncf = & dp -> dl_cb_fattr ;
88718876 nfs4_cb_getattr (& dp -> dl_cb_fattr );
88728877 spin_unlock (& ctx -> flc_lock );
@@ -8876,27 +8881,37 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode,
88768881 /* Recall delegation only if client didn't respond */
88778882 status = nfserrno (nfsd_open_break_lease (inode , NFSD_MAY_READ ));
88788883 if (status != nfserr_jukebox ||
8879- !nfsd_wait_for_delegreturn (rqstp , inode ))
8884+ !nfsd_wait_for_delegreturn (rqstp , inode )) {
8885+ nfs4_put_stid (& dp -> dl_stid );
88808886 return status ;
8887+ }
88818888 }
88828889 if (!ncf -> ncf_file_modified &&
88838890 (ncf -> ncf_initial_cinfo != ncf -> ncf_cb_change ||
88848891 ncf -> ncf_cur_fsize != ncf -> ncf_cb_fsize ))
88858892 ncf -> ncf_file_modified = true;
88868893 if (ncf -> ncf_file_modified ) {
8894+ int err ;
8895+
88878896 /*
88888897 * Per section 10.4.3 of RFC 8881, the server would
88898898 * not update the file's metadata with the client's
88908899 * modified size
88918900 */
88928901 attrs .ia_mtime = attrs .ia_ctime = current_time (inode );
8893- attrs .ia_valid = ATTR_MTIME | ATTR_CTIME ;
8894- setattr_copy (& nop_mnt_idmap , inode , & attrs );
8895- mark_inode_dirty (inode );
8902+ attrs .ia_valid = ATTR_MTIME | ATTR_CTIME | ATTR_DELEG ;
8903+ inode_lock (inode );
8904+ err = notify_change (& nop_mnt_idmap , dentry , & attrs , NULL );
8905+ inode_unlock (inode );
8906+ if (err ) {
8907+ nfs4_put_stid (& dp -> dl_stid );
8908+ return nfserrno (err );
8909+ }
88968910 ncf -> ncf_cur_fsize = ncf -> ncf_cb_fsize ;
88978911 * size = ncf -> ncf_cur_fsize ;
88988912 * modified = true;
88998913 }
8914+ nfs4_put_stid (& dp -> dl_stid );
89008915 return 0 ;
89018916 }
89028917 break ;
0 commit comments