1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * fs/hmdfs/hmdfs.h 4 * 5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 6 */ 7 8#ifndef HMDFS_H 9#define HMDFS_H 10 11#include <linux/fs.h> 12#include <linux/kfifo.h> 13#include <linux/kobject.h> 14#include <linux/kref.h> 15#include <linux/sched.h> 16#include <linux/version.h> 17 18#include "comm/protocol.h" 19 20#if KERNEL_VERSION(4, 15, 0) < LINUX_VERSION_CODE 21#define hmdfs_time_t timespec64 22#define hmdfs_time_compare timespec64_compare 23#define hmdfs_time_add timespec64_add 24#else 25#define hmdfs_time_t timespec 26#define hmdfs_time_compare timespec_compare 27#define hmdfs_time_add timespec_add 28#endif 29 30#define HMDFS_IOC 0xf2 31#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct hmdfs_share_control) 32#define HMDFS_IOC_GET_WRITEOPEN_CNT _IOR(HMDFS_IOC, 2, __u32) 33#define HMDFS_IOC_GET_DST_PATH _IOR(HMDFS_IOC, 3, __u32) 34 35 36#define HMDFS_PAGE_SIZE 4096 37#define HMDFS_PAGE_OFFSET 12 38 39/* max xattr value size, not include '\0' */ 40#define HMDFS_XATTR_SIZE_MAX 4096 41/* max listxattr response size, include '\0' */ 42#define HMDFS_LISTXATTR_SIZE_MAX 4096 43 44// 20 digits +'\0', Converted from a u64 integer 45#define HMDFS_ACCOUNT_HASH_MAX_LEN 21 46#define CTRL_PATH_MAX_LEN 21 47 48#define HMDFS_SUPER_MAGIC 0x20200302 49 50#define DEFAULT_WRITE_CACHE_TIMEOUT 30 51#define DEFAULT_SRV_REQ_MAX_ACTIVE 16 52 53#define HMDFS_INODE_INVALID_FILE_ID (1U << 31) 54#define HMDFS_FID_VER_BOOT_COOKIE_SHIFT 15 55 56/* According to task_struct instead of workqueue_struct */ 57#define HMDFS_WQ_NAME_LEN 16 58 59#define HMDFS_DEF_WB_TIMEOUT_MS 60000 60#define HMDFS_MAX_WB_TIMEOUT_MS 900000 61 62#define HMDFS_READPAGES_NR_MAX 32 63#define HMDFS_READPAGES_NR_DEF 1024 64 65#define HMDFS_CID_SIZE 64 66 67#define DIR_MODE 0771 68 69enum { 70 HMDFS_FEATURE_READPAGES = 1ULL << 0, 71 HMDFS_FEATURE_READPAGES_OPEN = 1ULL << 1, 72 HMDFS_ATOMIC_OPEN = 1ULL << 2, 73}; 74 75struct client_statistic; 76struct server_statistic; 77struct hmdfs_writeback; 78struct hmdfs_server_writeback; 79struct hmdfs_syncfs_info { 80 wait_queue_head_t wq; 81 atomic_t wait_count; 82 int remote_ret; 83 unsigned long long version; 84 85 /* Protect version in concurrent operations */ 86 spinlock_t v_lock; 87 /* 88 * Serialize hmdfs_sync_fs() process: 89 * |<- pending_list ->| exexuting |<- wait_list ->| 90 * syncfs_1 syncfs_2 (syncfs_3) syncfs_4 syncfs_5 91 * 92 * Abandon syncfs processes in pending_list after syncfs_3 finished; 93 * Pick the last syncfs process in wait_list after syncfs_3 finished; 94 */ 95 bool is_executing; 96 /* syncfs process arriving after current exexcuting syncfs */ 97 struct list_head wait_list; 98 /* syncfs process arriving before current exexcuting syncfs */ 99 struct list_head pending_list; 100 spinlock_t list_lock; 101}; 102 103struct hmdfs_share_table { 104 struct list_head item_list_head; 105 spinlock_t item_list_lock; 106 struct workqueue_struct *share_item_timeout_wq; 107 int item_cnt; 108 int max_cnt; 109}; 110 111struct hmdfs_sb_info { 112 /* list for all registered superblocks */ 113 struct list_head list; 114 struct mutex umount_mutex; 115 116 struct kobject kobj; 117 struct completion s_kobj_unregister; 118 struct super_block *sb; 119 struct super_block *lower_sb; 120 /* from mount, which is root */ 121 const struct cred *cred; 122 /* from update cmd, expected to be system */ 123 const struct cred *system_cred; 124 struct { 125 struct mutex node_lock; 126 struct list_head node_list; 127 atomic_t conn_seq; 128 unsigned long recent_ol; 129 } connections; 130 char *local_dst; 131 char *real_dst; 132 char *local_src; 133 char *cache_dir; 134 char *cloud_dir; 135 /* seq number for hmdfs super block */ 136 unsigned int seq; 137 138 /* 139 * This value indicate how long the pagecache stay valid(in seconds) in 140 * client if metadate(except iversion) is equal to server. This 141 * functionality is disabled if this value is 0. 142 */ 143 unsigned int write_cache_timeout; 144 unsigned int dcache_timeout; 145 unsigned int dcache_precision; 146 unsigned long dcache_threshold; 147 struct list_head client_cache; 148 struct list_head server_cache; 149 struct list_head to_delete; 150 struct mutex cache_list_lock; 151 152 /* local operation time statistic */ 153 struct server_statistic *s_server_statis; 154 155 /* client statistic */ 156 struct client_statistic *s_client_statis; 157 158 /* TIMEOUT of each command */ 159 struct kobject s_cmd_timeout_kobj; 160 struct completion s_timeout_kobj_unregister; 161 unsigned int s_cmd_timeout[F_SIZE]; 162 163 /* For case sensitive */ 164 bool s_case_sensitive; 165 166 /* For features supporting */ 167 u64 s_features; 168 169 /* number of pages to read */ 170 unsigned int s_readpages_nr; 171 172 /* For merge & device view */ 173 unsigned int s_merge_switch; 174 /* For cloud disk*/ 175 unsigned int s_cloud_disk_switch; 176 /* For writeback */ 177 struct hmdfs_writeback *h_wb; 178 /* For server writeback */ 179 struct hmdfs_server_writeback *h_swb; 180 181 /* syncfs info */ 182 struct hmdfs_syncfs_info hsi; 183 184 /* To bridge the userspace utils */ 185 struct kfifo notify_fifo; 186 spinlock_t notify_fifo_lock; 187 struct mutex cmd_handler_mutex; 188 189 /* For reboot detect */ 190 uint64_t boot_cookie; 191 /* offline process */ 192 unsigned int async_cb_delay; 193 /* For server handle requests */ 194 unsigned int async_req_max_active; 195 /* stash dirty pages during offline */ 196 bool s_offline_stash; 197 198 /* Timeout (ms) to retry writing remote pages */ 199 unsigned int wb_timeout_ms; 200 201 struct path stash_work_dir; 202 /* dentry cache */ 203 bool s_dentry_cache; 204 205 /* share table */ 206 struct hmdfs_share_table share_table; 207 208 /* msgs that are waiting for remote */ 209 struct list_head async_readdir_msg_list; 210 /* protect async_readdir_msg_list */ 211 spinlock_t async_readdir_msg_lock; 212 /* async readdir work that are queued but not finished */ 213 struct list_head async_readdir_work_list; 214 /* protect async_readdir_work_list */ 215 spinlock_t async_readdir_work_lock; 216 /* wait for async_readdir_work_list to be empty in umount */ 217 wait_queue_head_t async_readdir_wq; 218 /* don't allow async readdir */ 219 bool async_readdir_prohibit; 220 221 /* multi user */ 222 unsigned int user_id; 223}; 224 225static inline struct hmdfs_sb_info *hmdfs_sb(struct super_block *sb) 226{ 227 return sb->s_fs_info; 228} 229 230static inline bool hmdfs_is_stash_enabled(const struct hmdfs_sb_info *sbi) 231{ 232 return sbi->s_offline_stash; 233} 234 235struct hmdfs_dst_info{ 236 uint64_t local_path_len; 237 uint64_t local_path_pos; 238 uint64_t distributed_path_len; 239 uint64_t distributed_path_pos; 240 uint64_t bundle_name_len; 241 uint64_t bundle_name_pos; 242 uint64_t size; 243}; 244 245struct setattr_info { 246 loff_t size; 247 unsigned int valid; 248 umode_t mode; 249 kuid_t uid; 250 kgid_t gid; 251 long long atime; 252 long atime_nsec; 253 long long mtime; 254 long mtime_nsec; 255 long long ctime; 256 long ctime_nsec; 257}; 258 259struct hmdfs_file_info { 260 union { 261 struct { 262 struct rb_root root; 263 struct mutex comrade_list_lock; 264 }; 265 struct { 266 struct file *lower_file; 267 int device_id; 268 }; 269 }; 270 struct list_head comrade_list; 271}; 272 273static inline struct hmdfs_file_info *hmdfs_f(struct file *file) 274{ 275 return file->private_data; 276} 277 278// Almost all the source files want this, so... 279#include "inode.h" 280 281/* locking helpers */ 282static inline struct dentry *lock_parent(struct dentry *dentry) 283{ 284 struct dentry *dir = dget_parent(dentry); 285 286 inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); 287 return dir; 288} 289 290static inline void unlock_dir(struct dentry *dir) 291{ 292 inode_unlock(d_inode(dir)); 293 dput(dir); 294} 295 296extern uint64_t path_hash(const char *path, int len, bool case_sense); 297extern int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, 298 const char *name, unsigned int flags, 299 struct path *path); 300extern ssize_t hmdfs_remote_listxattr(struct dentry *dentry, char *buffer, 301 size_t size); 302 303int check_filename(const char *name, int len); 304 305int hmdfs_permission(struct mnt_idmap *idmap, struct inode *inode, int mask); 306 307int hmdfs_parse_options(struct hmdfs_sb_info *sbi, const char *data); 308 309/* Refer to comments in hmdfs_request_work_fn() */ 310#define HMDFS_SERVER_CTX_FLAGS (PF_KTHREAD | PF_WQ_WORKER | PF_NPROC_EXCEEDED) 311 312static inline bool is_current_hmdfs_server_ctx(void) 313{ 314 return ((current->flags & HMDFS_SERVER_CTX_FLAGS) == 315 HMDFS_SERVER_CTX_FLAGS); 316} 317 318extern uint64_t hmdfs_gen_boot_cookie(void); 319 320static inline bool str_n_case_eq(const char *s1, const char *s2, size_t len) 321{ 322 return !strncasecmp(s1, s2, len); 323} 324 325static inline bool qstr_case_eq(const struct qstr *q1, const struct qstr *q2) 326{ 327 return q1->len == q2->len && str_n_case_eq(q1->name, q2->name, q2->len); 328} 329 330static inline bool qstr_eq(const struct qstr *q1, const struct qstr *q2) 331{ 332 return q1->len == q2->len && !strncmp(q1->name, q2->name, q2->len); 333} 334 335/***************************************************************************** 336 * log print helpers 337 *****************************************************************************/ 338__printf(4, 5) void __hmdfs_log(const char *level, const bool ratelimited, 339 const char *function, const char *fmt, ...); 340#define hmdfs_err(fmt, ...) \ 341 __hmdfs_log(KERN_ERR, false, __func__, fmt, ##__VA_ARGS__) 342#define hmdfs_warning(fmt, ...) \ 343 __hmdfs_log(KERN_WARNING, false, __func__, fmt, ##__VA_ARGS__) 344#define hmdfs_info(fmt, ...) \ 345 __hmdfs_log(KERN_INFO, false, __func__, fmt, ##__VA_ARGS__) 346#define hmdfs_err_ratelimited(fmt, ...) \ 347 __hmdfs_log(KERN_ERR, true, __func__, fmt, ##__VA_ARGS__) 348#define hmdfs_warning_ratelimited(fmt, ...) \ 349 __hmdfs_log(KERN_WARNING, true, __func__, fmt, ##__VA_ARGS__) 350#define hmdfs_info_ratelimited(fmt, ...) \ 351 __hmdfs_log(KERN_INFO, true, __func__, fmt, ##__VA_ARGS__) 352#ifdef CONFIG_HMDFS_FS_DEBUG 353#define hmdfs_debug(fmt, ...) \ 354 __hmdfs_log(KERN_DEBUG, false, __func__, fmt, ##__VA_ARGS__) 355#define hmdfs_debug_ratelimited(fmt, ...) \ 356 __hmdfs_log(KERN_DEBUG, true, __func__, fmt, ##__VA_ARGS__) 357#else 358#define hmdfs_debug(fmt, ...) ((void)0) 359#define hmdfs_debug_ratelimited(fmt, ...) ((void)0) 360#endif 361 362/***************************************************************************** 363 * inode/file operations declartion 364 *****************************************************************************/ 365extern const struct inode_operations hmdfs_device_ops; 366extern const struct inode_operations hmdfs_root_ops; 367extern const struct file_operations hmdfs_root_fops; 368extern const struct file_operations hmdfs_device_fops; 369 370#endif // HMDFS_H 371