• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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