1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * fs/hmdfs/hmdfs_dentryfile.h
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8#ifndef HMDFS_DENTRYFILE_H
9#define HMDFS_DENTRYFILE_H
10
11#include "hmdfs.h"
12#include <linux/namei.h>
13
14/* use for escape from hmdfs file system, hmdfs hide follow names */
15#define CURRENT_DIR "."
16#define PARENT_DIR  ".."
17
18/* local dentry cache data */
19#define DENTRY_FILE_XATTR_NAME "user.hmdfs_cache"
20
21#define DENTRY_FILE_NAME_RETRY 10
22
23#define MAX_BUCKET_LEVEL 63
24#define BUCKET_BLOCKS	 2
25#define MAX_DIR_BUCKETS	 (1 << ((MAX_BUCKET_LEVEL / 2) - 1))
26
27#define CONFLICTING_FILE_CONST_SUFFIX "_conflict_dev"
28#define CONFLICTING_FILE_SUFFIX	      "_conflict_dev%u"
29#define CONFLICTING_DIR_SUFFIX	      "_remote_directory"
30
31#define POS_BIT_NUM	 64
32#define DEV_ID_BIT_NUM	 16
33#define GROUP_ID_BIT_NUM 39
34#define OFFSET_BIT_NUM	 8
35#define OFFSET_BIT_MASK	 0xFF
36
37#define DEFAULT_DCACHE_TIMEOUT	 30
38#define DEFAULT_DCACHE_PRECISION 10
39#define DEFAULT_DCACHE_THRESHOLD 1000
40#define HMDFS_STALE_REMOTE_ISIZE ULLONG_MAX
41
42/* Seconds per-week */
43#define MAX_DCACHE_TIMEOUT 604800
44
45struct hmdfs_iterate_callback {
46	struct dir_context ctx;
47	struct dir_context *caller;
48	int result;
49	struct rb_root *root;
50};
51
52/*
53 * 4096 = version(1) + bitmap(10) + reserved(5)
54 *        + nsl(80 * 43) + filename(80 * 8)
55 */
56#define DENTRYGROUP_SIZE       4096
57#define DENTRY_NAME_LEN	       8
58#define DENTRY_RESERVED_LENGTH 3
59#define DENTRY_PER_GROUP       80
60#define DENTRY_BITMAP_LENGTH   10
61#define DENTRY_GROUP_RESERVED  5
62#define DENTRYGROUP_HEADER     4096
63
64struct hmdfs_dentry {
65	__le32 hash;
66	__le16 i_mode;
67	__le16 namelen;
68	__le64 i_size;
69	/* modification time */
70	__le64 i_mtime;
71	/* modification time in nano scale */
72	__le32 i_mtime_nsec;
73	/* combination of inode number and generation */
74	__le64 i_ino;
75	__le32 i_flag;
76	/* reserved bytes for long term extend, total 43 bytes */
77	__u8 reserved[DENTRY_RESERVED_LENGTH];
78} __packed;
79
80/* 4K/51 Bytes = 80 dentries for per dentrygroup */
81struct hmdfs_dentry_group {
82	__u8 dentry_version; /* dentry version start from 1 */
83	__u8 bitmap[DENTRY_BITMAP_LENGTH];
84	struct hmdfs_dentry nsl[DENTRY_PER_GROUP];
85	__u8 filename[DENTRY_PER_GROUP][DENTRY_NAME_LEN];
86	__u8 reserved[DENTRY_GROUP_RESERVED];
87} __packed;
88
89/**
90 * The content of 1st 4k block in dentryfile.dat.
91 * Used for check whether the dcache can be used directly or
92 * need to rebuild.
93 *
94 * Since the ctime has 10ms or less precision, if the dcache
95 * rebuild at the same time of the dentry inode ctime, maybe
96 * non-consistent in dcache.
97 *	eg: create 1.jpg 2.jpg 3.jpg
98 *	    dcache rebuild may only has 1.jpg 2.jpg
99 * So, we need use these time to verify the dcache.
100 */
101struct hmdfs_dcache_header {
102	/* The time of dcache rebuild */
103	__le64 dcache_crtime;
104	__le64 dcache_crtime_nsec;
105
106	/* The directory inode ctime when dcache rebuild */
107	__le64 dentry_ctime;
108	__le64 dentry_ctime_nsec;
109
110	/* The dentry count */
111	__le64 num;
112
113	/* The case sensitive */
114	__u8 case_sensitive;
115} __packed;
116
117static inline loff_t get_dentry_group_pos(unsigned int bidx)
118{
119	return ((loff_t)bidx) * DENTRYGROUP_SIZE + DENTRYGROUP_HEADER;
120}
121
122static inline unsigned int get_dentry_group_cnt(struct inode *inode)
123{
124	loff_t size = i_size_read(inode);
125
126	return size >= DENTRYGROUP_HEADER ?
127		       (size - DENTRYGROUP_HEADER) / DENTRYGROUP_SIZE :
128		       0;
129}
130
131#define DENTRY_NAME_MAX_LEN (DENTRY_PER_GROUP * DENTRY_NAME_LEN)
132#define BITS_PER_BYTE	    8
133#define HMDFS_SLOT_LEN_BITS 3
134#define get_dentry_slots(x) (((x) + BITS_PER_BYTE - 1) >> HMDFS_SLOT_LEN_BITS)
135
136#define INUNUMBER_START 10000000
137
138#ifdef CONFIG_HMDFS_FS_PERMISSION
139#define DENTRY_FILE_PERM 0660
140#else
141#define DENTRY_FILE_PERM 0666
142#endif
143
144struct hmdfs_dcache_lookup_ctx {
145	struct hmdfs_sb_info *sbi;
146	const struct qstr *name;
147	struct file *filp;
148	__u32 hash;
149
150	/* for case sensitive */
151	unsigned int bidx;
152	struct hmdfs_dentry_group *page;
153
154	/* for case insensitive */
155	struct hmdfs_dentry *insense_de;
156	unsigned int insense_bidx;
157	struct hmdfs_dentry_group *insense_page;
158};
159
160extern void hmdfs_init_dcache_lookup_ctx(struct hmdfs_dcache_lookup_ctx *ctx,
161					 struct hmdfs_sb_info *sbi,
162					 const struct qstr *qstr,
163					 struct file *filp);
164
165int create_dentry(struct dentry *child_dentry, struct inode *inode,
166		  struct file *file, struct hmdfs_sb_info *sbi);
167int read_dentry(struct hmdfs_sb_info *sbi, char *file_name,
168		struct dir_context *ctx);
169struct hmdfs_dentry *hmdfs_find_dentry(struct dentry *child_dentry,
170				       struct hmdfs_dcache_lookup_ctx *ctx);
171void hmdfs_delete_dentry(struct dentry *d, struct file *filp);
172int hmdfs_rename_dentry(struct dentry *old_dentry, struct dentry *new_dentry,
173			struct file *old_filp, struct file *new_filp);
174int get_inonumber(void);
175struct file *create_local_dentry_file_cache(struct hmdfs_sb_info *sbi);
176int update_inode_to_dentry(struct dentry *child_dentry, struct inode *inode);
177struct file *cache_file_persistent(struct hmdfs_peer *con, struct file *filp,
178			   const char *relative_path, bool server);
179
180#define HMDFS_TYPE_COMMON	0
181#define HMDFS_TYPE_DOT		1
182#define HMDFS_TYPE_DENTRY	2
183#define HMDFS_TYPE_DENTRY_CACHE 3
184int hmdfs_file_type(const char *name);
185
186loff_t hmdfs_set_pos(unsigned long dev_id, unsigned long group_id,
187			    unsigned long offset);
188
189struct getdents_callback_real {
190	struct dir_context ctx;
191	struct path *parent_path;
192	loff_t num;
193	struct file *file;
194	struct hmdfs_sb_info *sbi;
195	const char *dir;
196};
197
198struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi,
199					struct path *path, loff_t *num,
200					const char *dir);
201
202#define DCACHE_LIFETIME 30
203
204struct clearcache_item {
205	uint64_t dev_id;
206	struct file *filp;
207	unsigned long time;
208	struct list_head list;
209	struct kref ref;
210	struct hmdfs_dentry_info *d_info;
211};
212
213void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path);
214
215struct remotecache_item {
216	struct hmdfs_peer *con;
217	struct list_head list;
218	__u8 drop_flag;
219};
220
221#define HMDFS_CFN_CID_SIZE 65
222#define HMDFS_SERVER_CID   ""
223
224struct cache_file_node {
225	struct list_head list;
226	struct hmdfs_sb_info *sbi;
227	char *relative_path;
228	u8 cid[HMDFS_CFN_CID_SIZE];
229	refcount_t ref;
230	bool server;
231	struct file *filp;
232};
233
234struct cache_file_item {
235	struct list_head list;
236	const char *name;
237};
238
239struct cache_file_callback {
240	struct dir_context ctx;
241	const char *dirname;
242	struct hmdfs_sb_info *sbi;
243	bool server;
244	struct list_head list;
245};
246
247int hmdfs_drop_remote_cache_dents(struct dentry *dentry);
248void hmdfs_send_drop_push(struct hmdfs_peer *con, const char *path);
249void hmdfs_mark_drop_flag(uint64_t device_id, struct dentry *dentry);
250void hmdfs_clear_drop_flag(struct dentry *dentry);
251void delete_in_cache_file(uint64_t dev_id, struct dentry *dentry);
252void create_in_cache_file(uint64_t dev_id, struct dentry *dentry);
253struct clearcache_item *hmdfs_find_cache_item(uint64_t dev_id,
254					      struct dentry *dentry);
255bool hmdfs_cache_revalidate(unsigned long conn_time, uint64_t dev_id,
256			    struct dentry *dentry);
257void hmdfs_remove_cache_filp(struct hmdfs_peer *con, struct dentry *dentry);
258int hmdfs_add_cache_list(uint64_t dev_id, struct dentry *dentry,
259			 struct file *filp);
260int hmdfs_clear_cache_dents(struct dentry *dentry, bool remove_cache);
261
262int hmdfs_root_unlink(uint64_t device_id, struct path *root_path,
263		      const char *unlink_dir, const char *unlink_name);
264struct dentry *hmdfs_root_mkdir(uint64_t device_id, const char *local_dst_path,
265				const char *mkdir_dir, const char *mkdir_name,
266				umode_t mode);
267struct dentry *hmdfs_root_create(uint64_t device_id, const char *local_dst_path,
268				 const char *create_dir,
269				 const char *create_name,
270				 umode_t mode, bool want_excl);
271int hmdfs_root_rmdir(uint64_t device_id, struct path *root_path,
272		     const char *rmdir_dir, const char *rmdir_name);
273int hmdfs_root_rename(struct hmdfs_sb_info *sbi, uint64_t device_id,
274		      const char *oldpath, const char *oldname,
275		      const char *newpath, const char *newname,
276		      unsigned int flags);
277
278int hmdfs_get_path_in_sb(struct super_block *sb, const char *name,
279			 unsigned int flags, struct path *path);
280
281int hmdfs_wlock_file(struct file *filp, loff_t start, loff_t len);
282int hmdfs_rlock_file(struct file *filp, loff_t start, loff_t len);
283int hmdfs_unlock_file(struct file *filp, loff_t start, loff_t len);
284long cache_file_truncate(struct hmdfs_sb_info *sbi, const struct path *path,
285			 loff_t length);
286ssize_t cache_file_read(struct hmdfs_sb_info *sbi, struct file *filp, void *buf,
287			size_t count, loff_t *pos);
288ssize_t cache_file_write(struct hmdfs_sb_info *sbi, struct file *filp,
289			 const void *buf, size_t count, loff_t *pos);
290int hmdfs_metainfo_read_nocred(struct file *filp,
291			void *buffer, int size, int bidx);
292int hmdfs_metainfo_read(struct hmdfs_sb_info *sbi, struct file *filp,
293			void *buffer, int buffersize, int bidx);
294
295bool get_remote_dentry_file(struct dentry *dentry, struct hmdfs_peer *con);
296void get_remote_dentry_file_sync(struct dentry *dentry, struct hmdfs_peer *con);
297int  get_cloud_cache_file(struct dentry *dentry, struct hmdfs_sb_info *sbi);
298
299void release_cache_item(struct kref *ref);
300void remove_cache_item(struct clearcache_item *item);
301
302void hmdfs_cfn_load(struct hmdfs_sb_info *sbi);
303void hmdfs_cfn_destroy(struct hmdfs_sb_info *sbi);
304struct cache_file_node *find_cfn(struct hmdfs_sb_info *sbi, const char *cid,
305				 const char *path, bool server);
306void release_cfn(struct cache_file_node *cfn);
307void destroy_cfn(struct hmdfs_sb_info *sbi);
308void remove_cfn(struct cache_file_node *cfn);
309int delete_dentry_file(struct file *filp);
310struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi,
311					   const char *recvpath,
312					   struct path *path);
313int write_header(struct file *filp, struct hmdfs_dcache_header *header);
314
315static inline struct list_head *get_list_head(struct hmdfs_sb_info *sbi,
316					      bool server)
317{
318	return ((server) ? &(sbi)->server_cache : &(sbi)->client_cache);
319}
320
321/*
322 * generate_u64_ino - generate a new 64 bit inode number
323 *
324 * @ino: origin 32 bit inode number
325 * @generation: origin 32 bit inode generation
326 *
327 * We need both remote inode number and generation to ensure the uniqueness of
328 * the local inode, thus we store inode->i_ino in lower 32 bits, and
329 * inode->i_generation in higher 32 bits.
330 */
331static inline uint64_t generate_u64_ino(unsigned long ino,
332					unsigned int generation)
333{
334	return (uint64_t)ino | ((uint64_t)generation << 32);
335}
336
337static inline bool cache_item_revalidate(unsigned long conn_time,
338					 unsigned long item_time,
339					 unsigned int timeout)
340{
341	return time_before_eq(jiffies, item_time + timeout * HZ) &&
342	       time_before_eq(conn_time, item_time);
343}
344
345__u32 hmdfs_dentry_hash(const struct qstr *qstr, bool case_sense);
346__u64 get_bucketaddr(unsigned int level, __u64 buckoffset);
347__u64 get_bucket_by_level(unsigned int level);
348unsigned int get_max_depth(struct file *filp);
349#endif
350