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 34enum HMDFS_FILE_TYPE { 35 HM_REG = 0, 36 HM_SYMLINK = 1, 37 HM_SHARE = 2, 38 39 HM_MAX_FILE_TYPE = 0XFF 40}; 41 42struct bydev_inode_info { 43 struct inode *lower_inode; 44 uint64_t ino; 45}; 46 47struct 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 62struct 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 70struct 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 80extern 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 88extern const struct dentry_operations hmdfs_dops; 89extern const struct dentry_operations hmdfs_dev_dops; 90 91/* local device operation */ 92extern const struct inode_operations hmdfs_file_iops_local; 93extern const struct file_operations hmdfs_file_fops_local; 94extern const struct inode_operations hmdfs_dir_inode_ops_local; 95extern const struct file_operations hmdfs_dir_ops_local; 96extern const struct file_operations hmdfs_dir_ops_share; 97extern const struct inode_operations hmdfs_symlink_iops_local; 98extern const struct inode_operations hmdfs_dir_inode_ops_share; 99 100/* remote device operation */ 101extern const struct inode_operations hmdfs_dev_file_iops_remote; 102extern const struct file_operations hmdfs_dev_file_fops_remote; 103extern const struct address_space_operations hmdfs_dev_file_aops_remote; 104extern const struct inode_operations hmdfs_dev_dir_inode_ops_remote; 105extern const struct file_operations hmdfs_dev_dir_ops_remote; 106 107/* cloud device operation */ 108extern const struct inode_operations hmdfs_dev_file_iops_cloud; 109extern const struct file_operations hmdfs_dev_file_fops_cloud; 110extern const struct address_space_operations hmdfs_dev_file_aops_cloud; 111extern const struct address_space_operations hmdfs_aops_cloud; 112extern const struct inode_operations hmdfs_dev_dir_inode_ops_cloud; 113extern const struct file_operations hmdfs_dev_dir_ops_cloud; 114extern int hmdfs_dev_unlink_from_con(struct hmdfs_peer *conn, 115 struct dentry *dentry); 116extern int hmdfs_dev_readdir_from_con(struct hmdfs_peer *con, struct file *file, 117 struct dir_context *ctx); 118int hmdfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); 119int hmdfs_rmdir(struct inode *dir, struct dentry *dentry); 120int hmdfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, 121 bool want_excl); 122int hmdfs_unlink(struct inode *dir, struct dentry *dentry); 123int hmdfs_remote_unlink(struct hmdfs_peer *conn, struct dentry *dentry); 124int hmdfs_rename(struct inode *old_dir, struct dentry *old_dentry, 125 struct inode *new_dir, struct dentry *new_dentry, 126 unsigned int flags); 127loff_t hmdfs_file_llseek_local(struct file *file, loff_t offset, int whence); 128 129ssize_t hmdfs_do_read_iter(struct file *file, struct iov_iter *iter, 130 loff_t *ppos); 131ssize_t hmdfs_do_write_iter(struct file *file, struct iov_iter *iter, 132 loff_t *ppos); 133 134int hmdfs_file_release_local(struct inode *inode, struct file *file); 135int hmdfs_file_mmap_local(struct file *file, struct vm_area_struct *vma); 136struct dentry *hmdfs_lookup(struct inode *parent_inode, 137 struct dentry *child_dentry, unsigned int flags); 138struct dentry *hmdfs_lookup_local(struct inode *parent_inode, 139 struct dentry *child_dentry, 140 unsigned int flags); 141struct dentry *hmdfs_lookup_remote(struct inode *parent_inode, 142 struct dentry *child_dentry, 143 unsigned int flags); 144int hmdfs_symlink_local(struct inode *dir, struct dentry *dentry, 145 const char *symname); 146int hmdfs_fsync_local(struct file *file, loff_t start, loff_t end, 147 int datasync); 148int hmdfs_symlink(struct inode *dir, struct dentry *dentry, 149 const char *symname); 150int hmdfs_fsync(struct file *file, loff_t start, loff_t end, int datasync); 151 152/***************************************************************************** 153 * common functions declaration 154 *****************************************************************************/ 155 156static inline struct hmdfs_dentry_info *hmdfs_d(struct dentry *dentry) 157{ 158 return dentry->d_fsdata; 159} 160 161static inline bool hm_isreg(uint8_t file_type) 162{ 163 return (file_type == HM_REG); 164} 165 166static inline bool hm_islnk(uint8_t file_type) 167{ 168 return (file_type == HM_SYMLINK); 169} 170 171static inline bool hm_isshare(uint8_t file_type) 172{ 173 return (file_type == HM_SHARE); 174} 175 176struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con, 177 struct hmdfs_lookup_ret *lookup_result, 178 struct inode *dir); 179struct hmdfs_lookup_ret *get_remote_inode_info(struct hmdfs_peer *con, 180 struct dentry *dentry, 181 unsigned int flags); 182void hmdfs_set_time(struct dentry *dentry, unsigned long time); 183struct inode *fill_inode_local(struct super_block *sb, 184 struct inode *lower_inode, const char *name); 185struct inode *fill_root_inode(struct super_block *sb, 186 struct hmdfs_sb_info *sbi, struct inode *lower_inode); 187struct inode *fill_device_inode(struct super_block *sb, 188 struct inode *lower_inode); 189struct 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); 194char *hmdfs_connect_path(const char *path, const char *name); 195 196char *hmdfs_get_dentry_relative_path(struct dentry *dentry); 197char *hmdfs_merge_get_dentry_relative_path(struct dentry *dentry); 198char *hmdfs_get_dentry_absolute_path(const char *rootdir, 199 const char *relative_path); 200int hmdfs_convert_lookup_flags(unsigned int hmdfs_flags, 201 unsigned int *vfs_flags); 202static 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 211static inline void hmdfs_put_lower_path(struct path *pname) 212{ 213 path_put(pname); 214} 215 216static 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 233static 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 */ 242static 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 260int init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry, 261 int dentry_type); 262 263#endif 264