@@ -269,7 +269,7 @@ static int dfscache_proc_show(struct seq_file *m, void *v)
269
269
list_for_each_entry (t , & ce -> tlist , list ) {
270
270
seq_printf (m , " %s%s\n" ,
271
271
t -> name ,
272
- ce -> tgthint == t ? " (target hint)" : "" );
272
+ READ_ONCE ( ce -> tgthint ) == t ? " (target hint)" : "" );
273
273
}
274
274
}
275
275
}
@@ -321,7 +321,7 @@ static inline void dump_tgts(const struct cache_entry *ce)
321
321
cifs_dbg (FYI , "target list:\n" );
322
322
list_for_each_entry (t , & ce -> tlist , list ) {
323
323
cifs_dbg (FYI , " %s%s\n" , t -> name ,
324
- ce -> tgthint == t ? " (target hint)" : "" );
324
+ READ_ONCE ( ce -> tgthint ) == t ? " (target hint)" : "" );
325
325
}
326
326
}
327
327
@@ -427,7 +427,7 @@ static int cache_entry_hash(const void *data, int size, unsigned int *hash)
427
427
/* Return target hint of a DFS cache entry */
428
428
static inline char * get_tgt_name (const struct cache_entry * ce )
429
429
{
430
- struct cache_dfs_tgt * t = ce -> tgthint ;
430
+ struct cache_dfs_tgt * t = READ_ONCE ( ce -> tgthint ) ;
431
431
432
432
return t ? t -> name : ERR_PTR (- ENOENT );
433
433
}
@@ -470,6 +470,7 @@ static struct cache_dfs_tgt *alloc_target(const char *name, int path_consumed)
470
470
static int copy_ref_data (const struct dfs_info3_param * refs , int numrefs ,
471
471
struct cache_entry * ce , const char * tgthint )
472
472
{
473
+ struct cache_dfs_tgt * target ;
473
474
int i ;
474
475
475
476
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,
496
497
ce -> numtgts ++ ;
497
498
}
498
499
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 );
501
503
502
504
return 0 ;
503
505
}
@@ -712,14 +714,15 @@ void dfs_cache_destroy(void)
712
714
static int update_cache_entry_locked (struct cache_entry * ce , const struct dfs_info3_param * refs ,
713
715
int numrefs )
714
716
{
717
+ struct cache_dfs_tgt * target ;
718
+ char * th = NULL ;
715
719
int rc ;
716
- char * s , * th = NULL ;
717
720
718
721
WARN_ON (!rwsem_is_locked (& htable_rw_lock ));
719
722
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 );
723
726
if (!th )
724
727
return - ENOMEM ;
725
728
}
@@ -896,7 +899,7 @@ static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl)
896
899
}
897
900
it -> it_path_consumed = t -> path_consumed ;
898
901
899
- if (ce -> tgthint == t )
902
+ if (READ_ONCE ( ce -> tgthint ) == t )
900
903
list_add (& it -> it_list , head );
901
904
else
902
905
list_add_tail (& it -> it_list , head );
@@ -1052,31 +1055,22 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses,
1052
1055
goto out_free_path ;
1053
1056
}
1054
1057
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 );
1065
1059
1066
1060
if (likely (!strcasecmp (it -> it_name , t -> name )))
1067
1061
goto out_unlock ;
1068
1062
1069
1063
list_for_each_entry (t , & ce -> tlist , list ) {
1070
1064
if (!strcasecmp (t -> name , it -> it_name )) {
1071
- ce -> tgthint = t ;
1065
+ WRITE_ONCE ( ce -> tgthint , t ) ;
1072
1066
cifs_dbg (FYI , "%s: new target hint: %s\n" , __func__ ,
1073
1067
it -> it_name );
1074
1068
break ;
1075
1069
}
1076
1070
}
1077
1071
1078
1072
out_unlock :
1079
- up_write (& htable_rw_lock );
1073
+ up_read (& htable_rw_lock );
1080
1074
out_free_path :
1081
1075
kfree (npath );
1082
1076
return rc ;
@@ -1106,29 +1100,28 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt
1106
1100
1107
1101
cifs_dbg (FYI , "%s: path: %s\n" , __func__ , path );
1108
1102
1109
- if (!down_write_trylock (& htable_rw_lock ))
1110
- return ;
1103
+ down_read (& htable_rw_lock );
1111
1104
1112
1105
ce = lookup_cache_entry (path );
1113
1106
if (IS_ERR (ce ))
1114
1107
goto out_unlock ;
1115
1108
1116
- t = ce -> tgthint ;
1109
+ t = READ_ONCE ( ce -> tgthint ) ;
1117
1110
1118
1111
if (unlikely (!strcasecmp (it -> it_name , t -> name )))
1119
1112
goto out_unlock ;
1120
1113
1121
1114
list_for_each_entry (t , & ce -> tlist , list ) {
1122
1115
if (!strcasecmp (t -> name , it -> it_name )) {
1123
- ce -> tgthint = t ;
1116
+ WRITE_ONCE ( ce -> tgthint , t ) ;
1124
1117
cifs_dbg (FYI , "%s: new target hint: %s\n" , __func__ ,
1125
1118
it -> it_name );
1126
1119
break ;
1127
1120
}
1128
1121
}
1129
1122
1130
1123
out_unlock :
1131
- up_write (& htable_rw_lock );
1124
+ up_read (& htable_rw_lock );
1132
1125
}
1133
1126
1134
1127
/**
0 commit comments