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 inode_operations hmdfs_dev_dir_inode_ops_cloud;
112 extern const struct file_operations hmdfs_dev_dir_ops_cloud;
113 extern int hmdfs_dev_unlink_from_con(struct hmdfs_peer *conn,
114 struct dentry *dentry);
115 extern int hmdfs_dev_readdir_from_con(struct hmdfs_peer *con, struct file *file,
116 struct dir_context *ctx);
117 int hmdfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
118 int hmdfs_rmdir(struct inode *dir, struct dentry *dentry);
119 int hmdfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
120 bool want_excl);
121 int hmdfs_unlink(struct inode *dir, struct dentry *dentry);
122 int hmdfs_remote_unlink(struct hmdfs_peer *conn, struct dentry *dentry);
123 int hmdfs_rename(struct inode *old_dir, struct dentry *old_dentry,
124 struct inode *new_dir, struct dentry *new_dentry,
125 unsigned int flags);
126 loff_t hmdfs_file_llseek_local(struct file *file, loff_t offset, int whence);
127
128 ssize_t hmdfs_do_read_iter(struct file *file, struct iov_iter *iter,
129 loff_t *ppos);
130 ssize_t hmdfs_do_write_iter(struct file *file, struct iov_iter *iter,
131 loff_t *ppos);
132
133 int hmdfs_file_release_local(struct inode *inode, struct file *file);
134 int hmdfs_file_mmap_local(struct file *file, struct vm_area_struct *vma);
135 struct dentry *hmdfs_lookup(struct inode *parent_inode,
136 struct dentry *child_dentry, unsigned int flags);
137 struct dentry *hmdfs_lookup_local(struct inode *parent_inode,
138 struct dentry *child_dentry,
139 unsigned int flags);
140 struct dentry *hmdfs_lookup_remote(struct inode *parent_inode,
141 struct dentry *child_dentry,
142 unsigned int flags);
143 int hmdfs_symlink_local(struct inode *dir, struct dentry *dentry,
144 const char *symname);
145 int hmdfs_fsync_local(struct file *file, loff_t start, loff_t end,
146 int datasync);
147 int hmdfs_symlink(struct inode *dir, struct dentry *dentry,
148 const char *symname);
149 int hmdfs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
150
151 /*****************************************************************************
152 * common functions declaration
153 *****************************************************************************/
154
hmdfs_d(struct dentry * dentry)155 static inline struct hmdfs_dentry_info *hmdfs_d(struct dentry *dentry)
156 {
157 return dentry->d_fsdata;
158 }
159
hm_isreg(uint8_t file_type)160 static inline bool hm_isreg(uint8_t file_type)
161 {
162 return (file_type == HM_REG);
163 }
164
hm_islnk(uint8_t file_type)165 static inline bool hm_islnk(uint8_t file_type)
166 {
167 return (file_type == HM_SYMLINK);
168 }
169
hm_isshare(uint8_t file_type)170 static inline bool hm_isshare(uint8_t file_type)
171 {
172 return (file_type == HM_SHARE);
173 }
174
175 struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con,
176 struct hmdfs_lookup_ret *lookup_result,
177 struct inode *dir);
178 struct hmdfs_lookup_ret *get_remote_inode_info(struct hmdfs_peer *con,
179 struct dentry *dentry,
180 unsigned int flags);
181 void hmdfs_set_time(struct dentry *dentry, unsigned long time);
182 struct inode *fill_inode_local(struct super_block *sb,
183 struct inode *lower_inode, const char *name);
184 struct inode *fill_root_inode(struct super_block *sb,
185 struct inode *lower_inode);
186 struct inode *fill_device_inode(struct super_block *sb,
187 struct inode *lower_inode);
188 struct hmdfs_lookup_ret *hmdfs_lookup_by_con(struct hmdfs_peer *con,
189 struct dentry *dentry,
190 struct qstr *qstr,
191 unsigned int flags,
192 const char *relative_path);
193 char *hmdfs_connect_path(const char *path, const char *name);
194
195 char *hmdfs_get_dentry_relative_path(struct dentry *dentry);
196 char *hmdfs_merge_get_dentry_relative_path(struct dentry *dentry);
197 char *hmdfs_get_dentry_absolute_path(const char *rootdir,
198 const char *relative_path);
199 int hmdfs_convert_lookup_flags(unsigned int hmdfs_flags,
200 unsigned int *vfs_flags);
hmdfs_get_lower_path(struct dentry * dent,struct path * pname)201 static inline void hmdfs_get_lower_path(struct dentry *dent, struct path *pname)
202 {
203 spin_lock(&hmdfs_d(dent)->lock);
204 pname->dentry = hmdfs_d(dent)->lower_path.dentry;
205 pname->mnt = hmdfs_d(dent)->lower_path.mnt;
206 path_get(pname);
207 spin_unlock(&hmdfs_d(dent)->lock);
208 }
209
hmdfs_put_lower_path(struct path * pname)210 static inline void hmdfs_put_lower_path(struct path *pname)
211 {
212 path_put(pname);
213 }
214
hmdfs_put_reset_lower_path(struct dentry * dent)215 static inline void hmdfs_put_reset_lower_path(struct dentry *dent)
216 {
217 struct path pname;
218
219 spin_lock(&hmdfs_d(dent)->lock);
220 if (hmdfs_d(dent)->lower_path.dentry) {
221 pname.dentry = hmdfs_d(dent)->lower_path.dentry;
222 pname.mnt = hmdfs_d(dent)->lower_path.mnt;
223 hmdfs_d(dent)->lower_path.dentry = NULL;
224 hmdfs_d(dent)->lower_path.mnt = NULL;
225 spin_unlock(&hmdfs_d(dent)->lock);
226 path_put(&pname);
227 } else {
228 spin_unlock(&hmdfs_d(dent)->lock);
229 }
230 }
231
hmdfs_set_lower_path(struct dentry * dent,struct path * pname)232 static inline void hmdfs_set_lower_path(struct dentry *dent, struct path *pname)
233 {
234 spin_lock(&hmdfs_d(dent)->lock);
235 hmdfs_d(dent)->lower_path.dentry = pname->dentry;
236 hmdfs_d(dent)->lower_path.mnt = pname->mnt;
237 spin_unlock(&hmdfs_d(dent)->lock);
238 }
239
240 /* Only reg file for HMDFS_LAYER_OTHER_* support xattr */
hmdfs_support_xattr(struct dentry * dentry)241 static inline bool hmdfs_support_xattr(struct dentry *dentry)
242 {
243 struct inode *inode = d_inode(dentry);
244 struct hmdfs_inode_info *info = hmdfs_i(inode);
245 struct hmdfs_dentry_info *gdi = hmdfs_d(dentry);
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 (!S_ISREG(inode->i_mode))
254 return false;
255
256 if (hm_islnk(gdi->file_type))
257 return false;
258
259 return true;
260 }
261
262 int init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry,
263 int dentry_type);
264
265 #endif
266