1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * fs/hmdfs/hmdfs_device_view.h
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8 #ifndef HMDFS_DEVICE_VIEW_H
9 #define HMDFS_DEVICE_VIEW_H
10
11 #include "hmdfs.h"
12
13 /*****************************************************************************
14 * macro defination
15 *****************************************************************************/
16
17 #define DEVICE_VIEW_ROOT "device_view"
18 #define MERGE_VIEW_ROOT "merge_view"
19 #define CLOUD_MERGE_VIEW_ROOT "cloud_merge_view"
20 #define UPDATE_LOCAL_DST "/device_view/local/"
21 #define UPDATE_CLOUD_DST "/device_view/cloud/"
22
23 #define DEVICE_VIEW_LOCAL "local"
24 #define DEVICE_VIEW_CLOUD "cloud"
25 #define CLOUD_CID "cloud"
26 #define CLOUD_DEVICE (1)
27
28 /*
29 * in order to distinguish from vfs, we define our own bitmask, this should
30 * covert to vfs bitmask while calling vfs apis
31 */
32 #define HMDFS_LOOKUP_REVAL 0x1
33
34 enum HMDFS_FILE_TYPE {
35 HM_REG = 0,
36 HM_SYMLINK = 1,
37 HM_SHARE = 2,
38
39 HM_MAX_FILE_TYPE = 0XFF
40 };
41
42 struct bydev_inode_info {
43 struct inode *lower_inode;
44 uint64_t ino;
45 };
46
47 struct hmdfs_dentry_info {
48 struct path lower_path;
49 unsigned long time;
50 struct list_head cache_list_head;
51 spinlock_t cache_list_lock;
52 struct list_head remote_cache_list_head;
53 struct mutex remote_cache_list_lock;
54 __u8 file_type;
55 __u8 dentry_type;
56 uint64_t device_id;
57 spinlock_t lock;
58 struct mutex cache_pull_lock;
59 int async_readdir_in_progress;
60 };
61
62 struct hmdfs_lookup_ret {
63 uint64_t i_size;
64 uint64_t i_mtime;
65 uint32_t i_mtime_nsec;
66 uint16_t i_mode;
67 uint64_t i_ino;
68 };
69
70 struct hmdfs_getattr_ret {
71 /*
72 * if stat->result_mask is 0, it means this remote getattr failed with
73 * look up, see details in hmdfs_server_getattr.
74 */
75 struct kstat stat;
76 uint32_t i_flags;
77 uint64_t fsid;
78 };
79
80 extern int hmdfs_remote_getattr(struct hmdfs_peer *conn, struct dentry *dentry,
81 unsigned int lookup_flags,
82 struct hmdfs_getattr_ret **getattr_result);
83
84 /*****************************************************************************
85 * local/remote inode/file operations
86 *****************************************************************************/
87
88 extern const struct dentry_operations hmdfs_dops;
89 extern const struct dentry_operations hmdfs_dev_dops;
90
91 /* local device operation */
92 extern const struct inode_operations hmdfs_file_iops_local;
93 extern const struct file_operations hmdfs_file_fops_local;
94 extern const struct inode_operations hmdfs_dir_inode_ops_local;
95 extern const struct file_operations hmdfs_dir_ops_local;
96 extern const struct file_operations hmdfs_dir_ops_share;
97 extern const struct inode_operations hmdfs_symlink_iops_local;
98 extern const struct inode_operations hmdfs_dir_inode_ops_share;
99
100 /* remote device operation */
101 extern const struct inode_operations hmdfs_dev_file_iops_remote;
102 extern const struct file_operations hmdfs_dev_file_fops_remote;
103 extern const struct address_space_operations hmdfs_dev_file_aops_remote;
104 extern const struct inode_operations hmdfs_dev_dir_inode_ops_remote;
105 extern const struct file_operations hmdfs_dev_dir_ops_remote;
106
107 /* cloud device operation */
108 extern const struct inode_operations hmdfs_dev_file_iops_cloud;
109 extern const struct file_operations hmdfs_dev_file_fops_cloud;
110 extern const struct address_space_operations hmdfs_dev_file_aops_cloud;
111 extern const struct address_space_operations hmdfs_aops_cloud;
112 extern const struct inode_operations hmdfs_dev_dir_inode_ops_cloud;
113 extern const struct file_operations hmdfs_dev_dir_ops_cloud;
114 extern int hmdfs_dev_unlink_from_con(struct hmdfs_peer *conn,
115 struct dentry *dentry);
116 extern int hmdfs_dev_readdir_from_con(struct hmdfs_peer *con, struct file *file,
117 struct dir_context *ctx);
118 int hmdfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
119 int hmdfs_rmdir(struct inode *dir, struct dentry *dentry);
120 int hmdfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
121 bool want_excl);
122 int hmdfs_unlink(struct inode *dir, struct dentry *dentry);
123 int hmdfs_remote_unlink(struct hmdfs_peer *conn, struct dentry *dentry);
124 int hmdfs_rename(struct inode *old_dir, struct dentry *old_dentry,
125 struct inode *new_dir, struct dentry *new_dentry,
126 unsigned int flags);
127 loff_t hmdfs_file_llseek_local(struct file *file, loff_t offset, int whence);
128
129 ssize_t hmdfs_do_read_iter(struct file *file, struct iov_iter *iter,
130 loff_t *ppos);
131 ssize_t hmdfs_do_write_iter(struct file *file, struct iov_iter *iter,
132 loff_t *ppos);
133
134 int hmdfs_file_release_local(struct inode *inode, struct file *file);
135 int hmdfs_file_mmap_local(struct file *file, struct vm_area_struct *vma);
136 struct dentry *hmdfs_lookup(struct inode *parent_inode,
137 struct dentry *child_dentry, unsigned int flags);
138 struct dentry *hmdfs_lookup_local(struct inode *parent_inode,
139 struct dentry *child_dentry,
140 unsigned int flags);
141 struct dentry *hmdfs_lookup_remote(struct inode *parent_inode,
142 struct dentry *child_dentry,
143 unsigned int flags);
144 int hmdfs_symlink_local(struct inode *dir, struct dentry *dentry,
145 const char *symname);
146 int hmdfs_fsync_local(struct file *file, loff_t start, loff_t end,
147 int datasync);
148 int hmdfs_symlink(struct inode *dir, struct dentry *dentry,
149 const char *symname);
150 int hmdfs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
151
152 /*****************************************************************************
153 * common functions declaration
154 *****************************************************************************/
155
hmdfs_d(struct dentry * dentry)156 static inline struct hmdfs_dentry_info *hmdfs_d(struct dentry *dentry)
157 {
158 return dentry->d_fsdata;
159 }
160
hm_isreg(uint8_t file_type)161 static inline bool hm_isreg(uint8_t file_type)
162 {
163 return (file_type == HM_REG);
164 }
165
hm_islnk(uint8_t file_type)166 static inline bool hm_islnk(uint8_t file_type)
167 {
168 return (file_type == HM_SYMLINK);
169 }
170
hm_isshare(uint8_t file_type)171 static inline bool hm_isshare(uint8_t file_type)
172 {
173 return (file_type == HM_SHARE);
174 }
175
176 struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con,
177 struct hmdfs_lookup_ret *lookup_result,
178 struct inode *dir);
179 struct hmdfs_lookup_ret *get_remote_inode_info(struct hmdfs_peer *con,
180 struct dentry *dentry,
181 unsigned int flags);
182 void hmdfs_set_time(struct dentry *dentry, unsigned long time);
183 struct inode *fill_inode_local(struct super_block *sb,
184 struct inode *lower_inode, const char *name);
185 struct inode *fill_root_inode(struct super_block *sb,
186 struct hmdfs_sb_info *sbi, struct inode *lower_inode);
187 struct inode *fill_device_inode(struct super_block *sb,
188 struct inode *lower_inode);
189 struct hmdfs_lookup_ret *hmdfs_lookup_by_con(struct hmdfs_peer *con,
190 struct dentry *dentry,
191 struct qstr *qstr,
192 unsigned int flags,
193 const char *relative_path);
194 char *hmdfs_connect_path(const char *path, const char *name);
195
196 char *hmdfs_get_dentry_relative_path(struct dentry *dentry);
197 char *hmdfs_merge_get_dentry_relative_path(struct dentry *dentry);
198 char *hmdfs_get_dentry_absolute_path(const char *rootdir,
199 const char *relative_path);
200 int hmdfs_convert_lookup_flags(unsigned int hmdfs_flags,
201 unsigned int *vfs_flags);
hmdfs_get_lower_path(struct dentry * dent,struct path * pname)202 static inline void hmdfs_get_lower_path(struct dentry *dent, struct path *pname)
203 {
204 spin_lock(&hmdfs_d(dent)->lock);
205 pname->dentry = hmdfs_d(dent)->lower_path.dentry;
206 pname->mnt = hmdfs_d(dent)->lower_path.mnt;
207 path_get(pname);
208 spin_unlock(&hmdfs_d(dent)->lock);
209 }
210
hmdfs_put_lower_path(struct path * pname)211 static inline void hmdfs_put_lower_path(struct path *pname)
212 {
213 path_put(pname);
214 }
215
hmdfs_put_reset_lower_path(struct dentry * dent)216 static inline void hmdfs_put_reset_lower_path(struct dentry *dent)
217 {
218 struct path pname;
219
220 spin_lock(&hmdfs_d(dent)->lock);
221 if (hmdfs_d(dent)->lower_path.dentry) {
222 pname.dentry = hmdfs_d(dent)->lower_path.dentry;
223 pname.mnt = hmdfs_d(dent)->lower_path.mnt;
224 hmdfs_d(dent)->lower_path.dentry = NULL;
225 hmdfs_d(dent)->lower_path.mnt = NULL;
226 spin_unlock(&hmdfs_d(dent)->lock);
227 path_put(&pname);
228 } else {
229 spin_unlock(&hmdfs_d(dent)->lock);
230 }
231 }
232
hmdfs_set_lower_path(struct dentry * dent,struct path * pname)233 static inline void hmdfs_set_lower_path(struct dentry *dent, struct path *pname)
234 {
235 spin_lock(&hmdfs_d(dent)->lock);
236 hmdfs_d(dent)->lower_path.dentry = pname->dentry;
237 hmdfs_d(dent)->lower_path.mnt = pname->mnt;
238 spin_unlock(&hmdfs_d(dent)->lock);
239 }
240
241 /* Only reg file for HMDFS_LAYER_OTHER_* support xattr */
hmdfs_support_xattr(struct dentry * dentry)242 static inline bool hmdfs_support_xattr(struct dentry *dentry)
243 {
244 struct inode *inode = d_inode(dentry);
245 struct hmdfs_inode_info *info = hmdfs_i(inode);
246
247 if (info->inode_type != HMDFS_LAYER_OTHER_LOCAL &&
248 info->inode_type != HMDFS_LAYER_OTHER_REMOTE &&
249 info->inode_type != HMDFS_LAYER_OTHER_MERGE &&
250 info->inode_type != HMDFS_LAYER_OTHER_MERGE_CLOUD)
251 return false;
252
253 if (info->inode_type == HMDFS_LAYER_OTHER_LOCAL &&
254 hm_islnk(hmdfs_d(dentry)->file_type))
255 return false;
256
257 return true;
258 }
259
260 int init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry,
261 int dentry_type);
262
263 #endif
264