• 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_get_dentry_absolute_path(const char *rootdir,
185 				     const char *relative_path);
186 int hmdfs_convert_lookup_flags(unsigned int hmdfs_flags,
187 			       unsigned int *vfs_flags);
hmdfs_get_lower_path(struct dentry * dent,struct path * pname)188 static inline void hmdfs_get_lower_path(struct dentry *dent, struct path *pname)
189 {
190 	spin_lock(&hmdfs_d(dent)->lock);
191 	pname->dentry = hmdfs_d(dent)->lower_path.dentry;
192 	pname->mnt = hmdfs_d(dent)->lower_path.mnt;
193 	path_get(pname);
194 	spin_unlock(&hmdfs_d(dent)->lock);
195 }
196 
hmdfs_put_lower_path(struct path * pname)197 static inline void hmdfs_put_lower_path(struct path *pname)
198 {
199 	path_put(pname);
200 }
201 
hmdfs_put_reset_lower_path(struct dentry * dent)202 static inline void hmdfs_put_reset_lower_path(struct dentry *dent)
203 {
204 	struct path pname;
205 
206 	spin_lock(&hmdfs_d(dent)->lock);
207 	if (hmdfs_d(dent)->lower_path.dentry) {
208 		pname.dentry = hmdfs_d(dent)->lower_path.dentry;
209 		pname.mnt = hmdfs_d(dent)->lower_path.mnt;
210 		hmdfs_d(dent)->lower_path.dentry = NULL;
211 		hmdfs_d(dent)->lower_path.mnt = NULL;
212 		spin_unlock(&hmdfs_d(dent)->lock);
213 		path_put(&pname);
214 	} else {
215 		spin_unlock(&hmdfs_d(dent)->lock);
216 	}
217 }
218 
hmdfs_set_lower_path(struct dentry * dent,struct path * pname)219 static inline void hmdfs_set_lower_path(struct dentry *dent, struct path *pname)
220 {
221 	spin_lock(&hmdfs_d(dent)->lock);
222 	hmdfs_d(dent)->lower_path.dentry = pname->dentry;
223 	hmdfs_d(dent)->lower_path.mnt = pname->mnt;
224 	spin_unlock(&hmdfs_d(dent)->lock);
225 }
226 
227 /* Only reg file for HMDFS_LAYER_OTHER_* support xattr */
hmdfs_support_xattr(struct dentry * dentry)228 static inline bool hmdfs_support_xattr(struct dentry *dentry)
229 {
230 	struct inode *inode = d_inode(dentry);
231 	struct hmdfs_inode_info *info = hmdfs_i(inode);
232 	struct hmdfs_dentry_info *gdi = hmdfs_d(dentry);
233 
234 	if (info->inode_type != HMDFS_LAYER_OTHER_LOCAL &&
235 	    info->inode_type != HMDFS_LAYER_OTHER_REMOTE)
236 		return false;
237 
238 	if (!S_ISREG(inode->i_mode))
239 		return false;
240 
241 	if (hm_islnk(gdi->file_type))
242 		return false;
243 
244 	return true;
245 }
246 
247 int init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry,
248 			   int dentry_type);
249 
250 #endif
251