Loading fs/cifs/dfs_cache.c +20 −27 Original line number Diff line number Diff line Loading @@ -269,7 +269,7 @@ static int dfscache_proc_show(struct seq_file *m, void *v) list_for_each_entry(t, &ce->tlist, list) { seq_printf(m, " %s%s\n", t->name, ce->tgthint == t ? " (target hint)" : ""); READ_ONCE(ce->tgthint) == t ? " (target hint)" : ""); } } } Loading Loading @@ -321,7 +321,7 @@ static inline void dump_tgts(const struct cache_entry *ce) cifs_dbg(FYI, "target list:\n"); list_for_each_entry(t, &ce->tlist, list) { cifs_dbg(FYI, " %s%s\n", t->name, ce->tgthint == t ? " (target hint)" : ""); READ_ONCE(ce->tgthint) == t ? " (target hint)" : ""); } } Loading Loading @@ -427,7 +427,7 @@ static int cache_entry_hash(const void *data, int size, unsigned int *hash) /* Return target hint of a DFS cache entry */ static inline char *get_tgt_name(const struct cache_entry *ce) { struct cache_dfs_tgt *t = ce->tgthint; struct cache_dfs_tgt *t = READ_ONCE(ce->tgthint); return t ? t->name : ERR_PTR(-ENOENT); } Loading Loading @@ -470,6 +470,7 @@ static struct cache_dfs_tgt *alloc_target(const char *name, int path_consumed) static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs, struct cache_entry *ce, const char *tgthint) { struct cache_dfs_tgt *target; int i; ce->ttl = max_t(int, refs[0].ttl, CACHE_MIN_TTL); Loading @@ -496,8 +497,9 @@ static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs, ce->numtgts++; } ce->tgthint = list_first_entry_or_null(&ce->tlist, struct cache_dfs_tgt, list); target = list_first_entry_or_null(&ce->tlist, struct cache_dfs_tgt, list); WRITE_ONCE(ce->tgthint, target); return 0; } Loading Loading @@ -712,14 +714,15 @@ void dfs_cache_destroy(void) static int update_cache_entry_locked(struct cache_entry *ce, const struct dfs_info3_param *refs, int numrefs) { struct cache_dfs_tgt *target; char *th = NULL; int rc; char *s, *th = NULL; WARN_ON(!rwsem_is_locked(&htable_rw_lock)); if (ce->tgthint) { s = ce->tgthint->name; th = kstrdup(s, GFP_ATOMIC); target = READ_ONCE(ce->tgthint); if (target) { th = kstrdup(target->name, GFP_ATOMIC); if (!th) return -ENOMEM; } Loading Loading @@ -896,7 +899,7 @@ static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl) } it->it_path_consumed = t->path_consumed; if (ce->tgthint == t) if (READ_ONCE(ce->tgthint) == t) list_add(&it->it_list, head); else list_add_tail(&it->it_list, head); Loading Loading @@ -1052,23 +1055,14 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, goto out_free_path; } up_read(&htable_rw_lock); down_write(&htable_rw_lock); ce = lookup_cache_entry(npath); if (IS_ERR(ce)) { rc = PTR_ERR(ce); goto out_unlock; } t = ce->tgthint; t = READ_ONCE(ce->tgthint); if (likely(!strcasecmp(it->it_name, t->name))) goto out_unlock; list_for_each_entry(t, &ce->tlist, list) { if (!strcasecmp(t->name, it->it_name)) { ce->tgthint = t; WRITE_ONCE(ce->tgthint, t); cifs_dbg(FYI, "%s: new target hint: %s\n", __func__, it->it_name); break; Loading @@ -1076,7 +1070,7 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, } out_unlock: up_write(&htable_rw_lock); up_read(&htable_rw_lock); out_free_path: kfree(npath); return rc; Loading Loading @@ -1106,21 +1100,20 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt cifs_dbg(FYI, "%s: path: %s\n", __func__, path); if (!down_write_trylock(&htable_rw_lock)) return; down_read(&htable_rw_lock); ce = lookup_cache_entry(path); if (IS_ERR(ce)) goto out_unlock; t = ce->tgthint; t = READ_ONCE(ce->tgthint); if (unlikely(!strcasecmp(it->it_name, t->name))) goto out_unlock; list_for_each_entry(t, &ce->tlist, list) { if (!strcasecmp(t->name, it->it_name)) { ce->tgthint = t; WRITE_ONCE(ce->tgthint, t); cifs_dbg(FYI, "%s: new target hint: %s\n", __func__, it->it_name); break; Loading @@ -1128,7 +1121,7 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt } out_unlock: up_write(&htable_rw_lock); up_read(&htable_rw_lock); } /** Loading Loading
fs/cifs/dfs_cache.c +20 −27 Original line number Diff line number Diff line Loading @@ -269,7 +269,7 @@ static int dfscache_proc_show(struct seq_file *m, void *v) list_for_each_entry(t, &ce->tlist, list) { seq_printf(m, " %s%s\n", t->name, ce->tgthint == t ? " (target hint)" : ""); READ_ONCE(ce->tgthint) == t ? " (target hint)" : ""); } } } Loading Loading @@ -321,7 +321,7 @@ static inline void dump_tgts(const struct cache_entry *ce) cifs_dbg(FYI, "target list:\n"); list_for_each_entry(t, &ce->tlist, list) { cifs_dbg(FYI, " %s%s\n", t->name, ce->tgthint == t ? " (target hint)" : ""); READ_ONCE(ce->tgthint) == t ? " (target hint)" : ""); } } Loading Loading @@ -427,7 +427,7 @@ static int cache_entry_hash(const void *data, int size, unsigned int *hash) /* Return target hint of a DFS cache entry */ static inline char *get_tgt_name(const struct cache_entry *ce) { struct cache_dfs_tgt *t = ce->tgthint; struct cache_dfs_tgt *t = READ_ONCE(ce->tgthint); return t ? t->name : ERR_PTR(-ENOENT); } Loading Loading @@ -470,6 +470,7 @@ static struct cache_dfs_tgt *alloc_target(const char *name, int path_consumed) static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs, struct cache_entry *ce, const char *tgthint) { struct cache_dfs_tgt *target; int i; ce->ttl = max_t(int, refs[0].ttl, CACHE_MIN_TTL); Loading @@ -496,8 +497,9 @@ static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs, ce->numtgts++; } ce->tgthint = list_first_entry_or_null(&ce->tlist, struct cache_dfs_tgt, list); target = list_first_entry_or_null(&ce->tlist, struct cache_dfs_tgt, list); WRITE_ONCE(ce->tgthint, target); return 0; } Loading Loading @@ -712,14 +714,15 @@ void dfs_cache_destroy(void) static int update_cache_entry_locked(struct cache_entry *ce, const struct dfs_info3_param *refs, int numrefs) { struct cache_dfs_tgt *target; char *th = NULL; int rc; char *s, *th = NULL; WARN_ON(!rwsem_is_locked(&htable_rw_lock)); if (ce->tgthint) { s = ce->tgthint->name; th = kstrdup(s, GFP_ATOMIC); target = READ_ONCE(ce->tgthint); if (target) { th = kstrdup(target->name, GFP_ATOMIC); if (!th) return -ENOMEM; } Loading Loading @@ -896,7 +899,7 @@ static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl) } it->it_path_consumed = t->path_consumed; if (ce->tgthint == t) if (READ_ONCE(ce->tgthint) == t) list_add(&it->it_list, head); else list_add_tail(&it->it_list, head); Loading Loading @@ -1052,23 +1055,14 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, goto out_free_path; } up_read(&htable_rw_lock); down_write(&htable_rw_lock); ce = lookup_cache_entry(npath); if (IS_ERR(ce)) { rc = PTR_ERR(ce); goto out_unlock; } t = ce->tgthint; t = READ_ONCE(ce->tgthint); if (likely(!strcasecmp(it->it_name, t->name))) goto out_unlock; list_for_each_entry(t, &ce->tlist, list) { if (!strcasecmp(t->name, it->it_name)) { ce->tgthint = t; WRITE_ONCE(ce->tgthint, t); cifs_dbg(FYI, "%s: new target hint: %s\n", __func__, it->it_name); break; Loading @@ -1076,7 +1070,7 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, } out_unlock: up_write(&htable_rw_lock); up_read(&htable_rw_lock); out_free_path: kfree(npath); return rc; Loading Loading @@ -1106,21 +1100,20 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt cifs_dbg(FYI, "%s: path: %s\n", __func__, path); if (!down_write_trylock(&htable_rw_lock)) return; down_read(&htable_rw_lock); ce = lookup_cache_entry(path); if (IS_ERR(ce)) goto out_unlock; t = ce->tgthint; t = READ_ONCE(ce->tgthint); if (unlikely(!strcasecmp(it->it_name, t->name))) goto out_unlock; list_for_each_entry(t, &ce->tlist, list) { if (!strcasecmp(t->name, it->it_name)) { ce->tgthint = t; WRITE_ONCE(ce->tgthint, t); cifs_dbg(FYI, "%s: new target hint: %s\n", __func__, it->it_name); break; Loading @@ -1128,7 +1121,7 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt } out_unlock: up_write(&htable_rw_lock); up_read(&htable_rw_lock); } /** Loading