162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * DFS referral cache routines 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2018-2019 Paulo Alcantara <palcantara@suse.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _CIFS_DFS_CACHE_H 962306a36Sopenharmony_ci#define _CIFS_DFS_CACHE_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/nls.h> 1262306a36Sopenharmony_ci#include <linux/list.h> 1362306a36Sopenharmony_ci#include <linux/uuid.h> 1462306a36Sopenharmony_ci#include "cifsglob.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciextern struct workqueue_struct *dfscache_wq; 1762306a36Sopenharmony_ciextern atomic_t dfs_cache_ttl; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define DFS_CACHE_TGT_LIST_INIT(var) \ 2062306a36Sopenharmony_ci { .tl_numtgts = 0, .tl_list = LIST_HEAD_INIT((var).tl_list), } 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define DFS_CACHE_TGT_LIST(var) \ 2362306a36Sopenharmony_ci struct dfs_cache_tgt_list var = DFS_CACHE_TGT_LIST_INIT(var) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistruct dfs_cache_tgt_list { 2662306a36Sopenharmony_ci int tl_numtgts; 2762306a36Sopenharmony_ci struct list_head tl_list; 2862306a36Sopenharmony_ci}; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistruct dfs_cache_tgt_iterator { 3162306a36Sopenharmony_ci char *it_name; 3262306a36Sopenharmony_ci int it_path_consumed; 3362306a36Sopenharmony_ci struct list_head it_list; 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ciint dfs_cache_init(void); 3762306a36Sopenharmony_civoid dfs_cache_destroy(void); 3862306a36Sopenharmony_ciextern const struct proc_ops dfscache_proc_ops; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciint dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nls_table *cp, 4162306a36Sopenharmony_ci int remap, const char *path, struct dfs_info3_param *ref, 4262306a36Sopenharmony_ci struct dfs_cache_tgt_list *tgt_list); 4362306a36Sopenharmony_ciint dfs_cache_noreq_find(const char *path, struct dfs_info3_param *ref, 4462306a36Sopenharmony_ci struct dfs_cache_tgt_list *tgt_list); 4562306a36Sopenharmony_civoid dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt_iterator *it); 4662306a36Sopenharmony_ciint dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iterator *it, 4762306a36Sopenharmony_ci struct dfs_info3_param *ref); 4862306a36Sopenharmony_ciint dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **share, 4962306a36Sopenharmony_ci char **prefix); 5062306a36Sopenharmony_cichar *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap); 5162306a36Sopenharmony_ciint dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb); 5262306a36Sopenharmony_civoid dfs_cache_refresh(struct work_struct *work); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic inline struct dfs_cache_tgt_iterator * 5562306a36Sopenharmony_cidfs_cache_get_next_tgt(struct dfs_cache_tgt_list *tl, 5662306a36Sopenharmony_ci struct dfs_cache_tgt_iterator *it) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci if (!tl || !tl->tl_numtgts || list_empty(&tl->tl_list) || 5962306a36Sopenharmony_ci !it || list_is_last(&it->it_list, &tl->tl_list)) 6062306a36Sopenharmony_ci return NULL; 6162306a36Sopenharmony_ci return list_next_entry(it, it_list); 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic inline struct dfs_cache_tgt_iterator * 6562306a36Sopenharmony_cidfs_cache_get_tgt_iterator(struct dfs_cache_tgt_list *tl) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci if (!tl) 6862306a36Sopenharmony_ci return NULL; 6962306a36Sopenharmony_ci return list_first_entry_or_null(&tl->tl_list, 7062306a36Sopenharmony_ci struct dfs_cache_tgt_iterator, 7162306a36Sopenharmony_ci it_list); 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic inline void dfs_cache_free_tgts(struct dfs_cache_tgt_list *tl) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci struct dfs_cache_tgt_iterator *it, *nit; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci if (!tl || !tl->tl_numtgts || list_empty(&tl->tl_list)) 7962306a36Sopenharmony_ci return; 8062306a36Sopenharmony_ci list_for_each_entry_safe(it, nit, &tl->tl_list, it_list) { 8162306a36Sopenharmony_ci list_del(&it->it_list); 8262306a36Sopenharmony_ci kfree(it->it_name); 8362306a36Sopenharmony_ci kfree(it); 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci tl->tl_numtgts = 0; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic inline const char * 8962306a36Sopenharmony_cidfs_cache_get_tgt_name(const struct dfs_cache_tgt_iterator *it) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci return it ? it->it_name : NULL; 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic inline int 9562306a36Sopenharmony_cidfs_cache_get_nr_tgts(const struct dfs_cache_tgt_list *tl) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci return tl ? tl->tl_numtgts : 0; 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic inline int dfs_cache_get_ttl(void) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci return atomic_read(&dfs_cache_ttl); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci#endif /* _CIFS_DFS_CACHE_H */ 106