@@ -269,7 +269,7 @@ static int dfscache_proc_show(struct seq_file *m, void *v)
269269 list_for_each_entry (t , & ce -> tlist , list ) {
270270 seq_printf (m , " %s%s\n" ,
271271 t -> name ,
272- ce -> tgthint == t ? " (target hint)" : "" );
272+ READ_ONCE ( ce -> tgthint ) == t ? " (target hint)" : "" );
273273 }
274274 }
275275 }
@@ -321,7 +321,7 @@ static inline void dump_tgts(const struct cache_entry *ce)
321321 cifs_dbg (FYI , "target list:\n" );
322322 list_for_each_entry (t , & ce -> tlist , list ) {
323323 cifs_dbg (FYI , " %s%s\n" , t -> name ,
324- ce -> tgthint == t ? " (target hint)" : "" );
324+ READ_ONCE ( ce -> tgthint ) == t ? " (target hint)" : "" );
325325 }
326326}
327327
@@ -427,7 +427,7 @@ static int cache_entry_hash(const void *data, int size, unsigned int *hash)
427427/* Return target hint of a DFS cache entry */
428428static inline char * get_tgt_name (const struct cache_entry * ce )
429429{
430- struct cache_dfs_tgt * t = ce -> tgthint ;
430+ struct cache_dfs_tgt * t = READ_ONCE ( ce -> tgthint ) ;
431431
432432 return t ? t -> name : ERR_PTR (- ENOENT );
433433}
@@ -470,6 +470,7 @@ static struct cache_dfs_tgt *alloc_target(const char *name, int path_consumed)
470470static int copy_ref_data (const struct dfs_info3_param * refs , int numrefs ,
471471 struct cache_entry * ce , const char * tgthint )
472472{
473+ struct cache_dfs_tgt * target ;
473474 int i ;
474475
475476 ce -> ttl = max_t (int , refs [0 ].ttl , CACHE_MIN_TTL );
@@ -496,8 +497,9 @@ static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs,
496497 ce -> numtgts ++ ;
497498 }
498499
499- ce -> tgthint = list_first_entry_or_null (& ce -> tlist ,
500- struct cache_dfs_tgt , list );
500+ target = list_first_entry_or_null (& ce -> tlist , struct cache_dfs_tgt ,
501+ list );
502+ WRITE_ONCE (ce -> tgthint , target );
501503
502504 return 0 ;
503505}
@@ -712,14 +714,15 @@ void dfs_cache_destroy(void)
712714static int update_cache_entry_locked (struct cache_entry * ce , const struct dfs_info3_param * refs ,
713715 int numrefs )
714716{
717+ struct cache_dfs_tgt * target ;
718+ char * th = NULL ;
715719 int rc ;
716- char * s , * th = NULL ;
717720
718721 WARN_ON (!rwsem_is_locked (& htable_rw_lock ));
719722
720- if (ce -> tgthint ) {
721- s = ce -> tgthint -> name ;
722- th = kstrdup (s , GFP_ATOMIC );
723+ target = READ_ONCE (ce -> tgthint );
724+ if ( target ) {
725+ th = kstrdup (target -> name , GFP_ATOMIC );
723726 if (!th )
724727 return - ENOMEM ;
725728 }
@@ -896,7 +899,7 @@ static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl)
896899 }
897900 it -> it_path_consumed = t -> path_consumed ;
898901
899- if (ce -> tgthint == t )
902+ if (READ_ONCE ( ce -> tgthint ) == t )
900903 list_add (& it -> it_list , head );
901904 else
902905 list_add_tail (& it -> it_list , head );
@@ -1052,31 +1055,22 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses,
10521055 goto out_free_path ;
10531056 }
10541057
1055- up_read (& htable_rw_lock );
1056- down_write (& htable_rw_lock );
1057-
1058- ce = lookup_cache_entry (npath );
1059- if (IS_ERR (ce )) {
1060- rc = PTR_ERR (ce );
1061- goto out_unlock ;
1062- }
1063-
1064- t = ce -> tgthint ;
1058+ t = READ_ONCE (ce -> tgthint );
10651059
10661060 if (likely (!strcasecmp (it -> it_name , t -> name )))
10671061 goto out_unlock ;
10681062
10691063 list_for_each_entry (t , & ce -> tlist , list ) {
10701064 if (!strcasecmp (t -> name , it -> it_name )) {
1071- ce -> tgthint = t ;
1065+ WRITE_ONCE ( ce -> tgthint , t ) ;
10721066 cifs_dbg (FYI , "%s: new target hint: %s\n" , __func__ ,
10731067 it -> it_name );
10741068 break ;
10751069 }
10761070 }
10771071
10781072out_unlock :
1079- up_write (& htable_rw_lock );
1073+ up_read (& htable_rw_lock );
10801074out_free_path :
10811075 kfree (npath );
10821076 return rc ;
@@ -1106,29 +1100,28 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt
11061100
11071101 cifs_dbg (FYI , "%s: path: %s\n" , __func__ , path );
11081102
1109- if (!down_write_trylock (& htable_rw_lock ))
1110- return ;
1103+ down_read (& htable_rw_lock );
11111104
11121105 ce = lookup_cache_entry (path );
11131106 if (IS_ERR (ce ))
11141107 goto out_unlock ;
11151108
1116- t = ce -> tgthint ;
1109+ t = READ_ONCE ( ce -> tgthint ) ;
11171110
11181111 if (unlikely (!strcasecmp (it -> it_name , t -> name )))
11191112 goto out_unlock ;
11201113
11211114 list_for_each_entry (t , & ce -> tlist , list ) {
11221115 if (!strcasecmp (t -> name , it -> it_name )) {
1123- ce -> tgthint = t ;
1116+ WRITE_ONCE ( ce -> tgthint , t ) ;
11241117 cifs_dbg (FYI , "%s: new target hint: %s\n" , __func__ ,
11251118 it -> it_name );
11261119 break ;
11271120 }
11281121 }
11291122
11301123out_unlock :
1131- up_write (& htable_rw_lock );
1124+ up_read (& htable_rw_lock );
11321125}
11331126
11341127/**
0 commit comments