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