@@ -139,9 +139,10 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key,
139139 vnode -> cb_expires_at = ktime_get_real_seconds ();
140140 } else {
141141 vnode -> cb_expires_at = scb -> callback .expires_at ;
142- old_cbi = vnode -> cb_interest ;
142+ old_cbi = rcu_dereference_protected (vnode -> cb_interest ,
143+ lockdep_is_held (& vnode -> cb_lock .lock ));
143144 if (cbi != old_cbi )
144- vnode -> cb_interest = afs_get_cb_interest (cbi );
145+ rcu_assign_pointer ( vnode -> cb_interest , afs_get_cb_interest (cbi ) );
145146 else
146147 old_cbi = NULL ;
147148 set_bit (AFS_VNODE_CB_PROMISED , & vnode -> flags );
@@ -245,9 +246,10 @@ static void afs_apply_callback(struct afs_fs_cursor *fc,
245246
246247 if (!afs_cb_is_broken (cb_break , vnode , fc -> cbi )) {
247248 vnode -> cb_expires_at = cb -> expires_at ;
248- old = vnode -> cb_interest ;
249+ old = rcu_dereference_protected (vnode -> cb_interest ,
250+ lockdep_is_held (& vnode -> cb_lock .lock ));
249251 if (old != fc -> cbi ) {
250- vnode -> cb_interest = afs_get_cb_interest (fc -> cbi );
252+ rcu_assign_pointer ( vnode -> cb_interest , afs_get_cb_interest (fc -> cbi ) );
251253 afs_put_cb_interest (afs_v2net (vnode ), old );
252254 }
253255 set_bit (AFS_VNODE_CB_PROMISED , & vnode -> flags );
@@ -565,36 +567,46 @@ void afs_zap_data(struct afs_vnode *vnode)
565567 */
566568bool afs_check_validity (struct afs_vnode * vnode )
567569{
570+ struct afs_cb_interest * cbi ;
571+ struct afs_server * server ;
572+ struct afs_volume * volume = vnode -> volume ;
568573 time64_t now = ktime_get_real_seconds ();
569574 bool valid ;
575+ unsigned int cb_break , cb_s_break , cb_v_break ;
576+ int seq = 0 ;
570577
571- /* Quickly check the callback state. Ideally, we'd use read_seqbegin
572- * here, but we have no way to pass the net namespace to the RCU
573- * cleanup for the server record.
574- */
575- read_seqlock_excl (& vnode -> cb_lock );
576-
577- if (test_bit (AFS_VNODE_CB_PROMISED , & vnode -> flags )) {
578- if (vnode -> cb_s_break != vnode -> cb_interest -> server -> cb_s_break ||
579- vnode -> cb_v_break != vnode -> volume -> cb_v_break ) {
580- vnode -> cb_s_break = vnode -> cb_interest -> server -> cb_s_break ;
581- vnode -> cb_v_break = vnode -> volume -> cb_v_break ;
582- valid = false;
583- } else if (test_bit (AFS_VNODE_ZAP_DATA , & vnode -> flags )) {
584- valid = false;
585- } else if (vnode -> cb_expires_at - 10 <= now ) {
586- valid = false;
587- } else {
578+ do {
579+ read_seqbegin_or_lock (& vnode -> cb_lock , & seq );
580+ cb_v_break = READ_ONCE (volume -> cb_v_break );
581+ cb_break = vnode -> cb_break ;
582+
583+ if (test_bit (AFS_VNODE_CB_PROMISED , & vnode -> flags )) {
584+ cbi = rcu_dereference (vnode -> cb_interest );
585+ server = rcu_dereference (cbi -> server );
586+ cb_s_break = READ_ONCE (server -> cb_s_break );
587+
588+ if (vnode -> cb_s_break != cb_s_break ||
589+ vnode -> cb_v_break != cb_v_break ) {
590+ vnode -> cb_s_break = cb_s_break ;
591+ vnode -> cb_v_break = cb_v_break ;
592+ valid = false;
593+ } else if (test_bit (AFS_VNODE_ZAP_DATA , & vnode -> flags )) {
594+ valid = false;
595+ } else if (vnode -> cb_expires_at - 10 <= now ) {
596+ valid = false;
597+ } else {
598+ valid = true;
599+ }
600+ } else if (test_bit (AFS_VNODE_DELETED , & vnode -> flags )) {
588601 valid = true;
602+ } else {
603+ vnode -> cb_v_break = cb_v_break ;
604+ valid = false;
589605 }
590- } else if (test_bit (AFS_VNODE_DELETED , & vnode -> flags )) {
591- valid = true;
592- } else {
593- vnode -> cb_v_break = vnode -> volume -> cb_v_break ;
594- valid = false;
595- }
596606
597- read_sequnlock_excl (& vnode -> cb_lock );
607+ } while (need_seqretry (& vnode -> cb_lock , seq ));
608+
609+ done_seqretry (& vnode -> cb_lock , seq );
598610 return valid ;
599611}
600612
@@ -616,7 +628,9 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
616628 vnode -> fid .vid , vnode -> fid .vnode , vnode -> flags ,
617629 key_serial (key ));
618630
631+ rcu_read_lock ();
619632 valid = afs_check_validity (vnode );
633+ rcu_read_unlock ();
620634
621635 if (test_bit (AFS_VNODE_DELETED , & vnode -> flags ))
622636 clear_nlink (& vnode -> vfs_inode );
@@ -703,6 +717,7 @@ int afs_drop_inode(struct inode *inode)
703717 */
704718void afs_evict_inode (struct inode * inode )
705719{
720+ struct afs_cb_interest * cbi ;
706721 struct afs_vnode * vnode ;
707722
708723 vnode = AFS_FS_I (inode );
@@ -719,10 +734,14 @@ void afs_evict_inode(struct inode *inode)
719734 truncate_inode_pages_final (& inode -> i_data );
720735 clear_inode (inode );
721736
722- if (vnode -> cb_interest ) {
723- afs_put_cb_interest (afs_i2net (inode ), vnode -> cb_interest );
724- vnode -> cb_interest = NULL ;
737+ write_seqlock (& vnode -> cb_lock );
738+ cbi = rcu_dereference_protected (vnode -> cb_interest ,
739+ lockdep_is_held (& vnode -> cb_lock .lock ));
740+ if (cbi ) {
741+ afs_put_cb_interest (afs_i2net (inode ), cbi );
742+ rcu_assign_pointer (vnode -> cb_interest , NULL );
725743 }
744+ write_sequnlock (& vnode -> cb_lock );
726745
727746 while (!list_empty (& vnode -> wb_keys )) {
728747 struct afs_wb_key * wbk = list_entry (vnode -> wb_keys .next ,
0 commit comments