162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * fs/hmdfs/hmdfs_device_view.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef HMDFS_DEVICE_VIEW_H
962306a36Sopenharmony_ci#define HMDFS_DEVICE_VIEW_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "hmdfs.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/*****************************************************************************
1462306a36Sopenharmony_ci * macro defination
1562306a36Sopenharmony_ci *****************************************************************************/
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define DEVICE_VIEW_ROOT "device_view"
1862306a36Sopenharmony_ci#define MERGE_VIEW_ROOT	 "merge_view"
1962306a36Sopenharmony_ci#define CLOUD_MERGE_VIEW_ROOT	 "cloud_merge_view"
2062306a36Sopenharmony_ci#define UPDATE_LOCAL_DST "/device_view/local/"
2162306a36Sopenharmony_ci#define UPDATE_CLOUD_DST "/device_view/cloud/"
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define DEVICE_VIEW_LOCAL "local"
2462306a36Sopenharmony_ci#define DEVICE_VIEW_CLOUD "cloud"
2562306a36Sopenharmony_ci#define CLOUD_CID "cloud"
2662306a36Sopenharmony_ci#define CLOUD_DEVICE (1)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/*
2962306a36Sopenharmony_ci * in order to distinguish from vfs, we define our own bitmask, this should
3062306a36Sopenharmony_ci * covert to vfs bitmask while calling vfs apis
3162306a36Sopenharmony_ci */
3262306a36Sopenharmony_ci#define HMDFS_LOOKUP_REVAL 0x1
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cienum HMDFS_FILE_TYPE {
3562306a36Sopenharmony_ci	HM_REG = 0,
3662306a36Sopenharmony_ci	HM_SYMLINK = 1,
3762306a36Sopenharmony_ci	HM_SHARE = 2,
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	HM_MAX_FILE_TYPE = 0XFF
4062306a36Sopenharmony_ci};
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistruct bydev_inode_info {
4362306a36Sopenharmony_ci	struct inode *lower_inode;
4462306a36Sopenharmony_ci	uint64_t ino;
4562306a36Sopenharmony_ci};
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistruct hmdfs_dentry_info {
4862306a36Sopenharmony_ci	struct path lower_path;
4962306a36Sopenharmony_ci	unsigned long time;
5062306a36Sopenharmony_ci	struct list_head cache_list_head;
5162306a36Sopenharmony_ci	spinlock_t cache_list_lock;
5262306a36Sopenharmony_ci	struct list_head remote_cache_list_head;
5362306a36Sopenharmony_ci	struct mutex remote_cache_list_lock;
5462306a36Sopenharmony_ci	__u8 file_type;
5562306a36Sopenharmony_ci	__u8 dentry_type;
5662306a36Sopenharmony_ci	uint64_t device_id;
5762306a36Sopenharmony_ci	spinlock_t lock;
5862306a36Sopenharmony_ci	struct mutex cache_pull_lock;
5962306a36Sopenharmony_ci	int async_readdir_in_progress;
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistruct hmdfs_lookup_ret {
6362306a36Sopenharmony_ci	uint64_t i_size;
6462306a36Sopenharmony_ci	uint64_t i_mtime;
6562306a36Sopenharmony_ci	uint32_t i_mtime_nsec;
6662306a36Sopenharmony_ci	uint16_t i_mode;
6762306a36Sopenharmony_ci	uint64_t i_ino;
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistruct hmdfs_getattr_ret {
7162306a36Sopenharmony_ci	/*
7262306a36Sopenharmony_ci	 * if stat->result_mask is 0, it means this remote getattr failed with
7362306a36Sopenharmony_ci	 * look up, see details in hmdfs_server_getattr.
7462306a36Sopenharmony_ci	 */
7562306a36Sopenharmony_ci	struct kstat stat;
7662306a36Sopenharmony_ci	uint32_t i_flags;
7762306a36Sopenharmony_ci	uint64_t fsid;
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciextern int hmdfs_remote_getattr(struct hmdfs_peer *conn, struct dentry *dentry,
8162306a36Sopenharmony_ci				unsigned int lookup_flags,
8262306a36Sopenharmony_ci				struct hmdfs_getattr_ret **getattr_result);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/*****************************************************************************
8562306a36Sopenharmony_ci * local/remote inode/file operations
8662306a36Sopenharmony_ci *****************************************************************************/
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciextern const struct dentry_operations hmdfs_dops;
8962306a36Sopenharmony_ciextern const struct dentry_operations hmdfs_dev_dops;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/* local device operation */
9262306a36Sopenharmony_ciextern const struct inode_operations hmdfs_file_iops_local;
9362306a36Sopenharmony_ciextern const struct file_operations hmdfs_file_fops_local;
9462306a36Sopenharmony_ciextern const struct inode_operations hmdfs_dir_inode_ops_local;
9562306a36Sopenharmony_ciextern const struct file_operations hmdfs_dir_ops_local;
9662306a36Sopenharmony_ciextern const struct file_operations hmdfs_dir_ops_share;
9762306a36Sopenharmony_ciextern const struct inode_operations hmdfs_symlink_iops_local;
9862306a36Sopenharmony_ciextern const struct inode_operations hmdfs_dir_inode_ops_share;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/* remote device operation */
10162306a36Sopenharmony_ciextern const struct inode_operations hmdfs_dev_file_iops_remote;
10262306a36Sopenharmony_ciextern const struct file_operations hmdfs_dev_file_fops_remote;
10362306a36Sopenharmony_ciextern const struct address_space_operations hmdfs_dev_file_aops_remote;
10462306a36Sopenharmony_ciextern const struct inode_operations hmdfs_dev_dir_inode_ops_remote;
10562306a36Sopenharmony_ciextern const struct file_operations hmdfs_dev_dir_ops_remote;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/* cloud device operation */
10862306a36Sopenharmony_ciextern const struct inode_operations hmdfs_dev_file_iops_cloud;
10962306a36Sopenharmony_ciextern const struct file_operations hmdfs_dev_file_fops_cloud;
11062306a36Sopenharmony_ciextern const struct address_space_operations hmdfs_dev_file_aops_cloud;
11162306a36Sopenharmony_ciextern const struct address_space_operations hmdfs_aops_cloud;
11262306a36Sopenharmony_ciextern const struct inode_operations hmdfs_dev_dir_inode_ops_cloud;
11362306a36Sopenharmony_ciextern const struct file_operations hmdfs_dev_dir_ops_cloud;
11462306a36Sopenharmony_ciextern int hmdfs_dev_unlink_from_con(struct hmdfs_peer *conn,
11562306a36Sopenharmony_ci				     struct dentry *dentry);
11662306a36Sopenharmony_ciextern int hmdfs_dev_readdir_from_con(struct hmdfs_peer *con, struct file *file,
11762306a36Sopenharmony_ci				      struct dir_context *ctx);
11862306a36Sopenharmony_ciint hmdfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
11962306a36Sopenharmony_ciint hmdfs_rmdir(struct inode *dir, struct dentry *dentry);
12062306a36Sopenharmony_ciint hmdfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
12162306a36Sopenharmony_ci		 bool want_excl);
12262306a36Sopenharmony_ciint hmdfs_unlink(struct inode *dir, struct dentry *dentry);
12362306a36Sopenharmony_ciint hmdfs_remote_unlink(struct hmdfs_peer *conn, struct dentry *dentry);
12462306a36Sopenharmony_ciint hmdfs_rename(struct inode *old_dir, struct dentry *old_dentry,
12562306a36Sopenharmony_ci		 struct inode *new_dir, struct dentry *new_dentry,
12662306a36Sopenharmony_ci		 unsigned int flags);
12762306a36Sopenharmony_ciloff_t hmdfs_file_llseek_local(struct file *file, loff_t offset, int whence);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cissize_t hmdfs_do_read_iter(struct file *file, struct iov_iter *iter,
13062306a36Sopenharmony_ci	loff_t *ppos);
13162306a36Sopenharmony_cissize_t hmdfs_do_write_iter(struct file *file, struct iov_iter *iter,
13262306a36Sopenharmony_ci	loff_t *ppos);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ciint hmdfs_file_release_local(struct inode *inode, struct file *file);
13562306a36Sopenharmony_ciint hmdfs_file_mmap_local(struct file *file, struct vm_area_struct *vma);
13662306a36Sopenharmony_cistruct dentry *hmdfs_lookup(struct inode *parent_inode,
13762306a36Sopenharmony_ci			    struct dentry *child_dentry, unsigned int flags);
13862306a36Sopenharmony_cistruct dentry *hmdfs_lookup_local(struct inode *parent_inode,
13962306a36Sopenharmony_ci				  struct dentry *child_dentry,
14062306a36Sopenharmony_ci				  unsigned int flags);
14162306a36Sopenharmony_cistruct dentry *hmdfs_lookup_remote(struct inode *parent_inode,
14262306a36Sopenharmony_ci				   struct dentry *child_dentry,
14362306a36Sopenharmony_ci				   unsigned int flags);
14462306a36Sopenharmony_ciint hmdfs_symlink_local(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry,
14562306a36Sopenharmony_ci			const char *symname);
14662306a36Sopenharmony_ciint hmdfs_fsync_local(struct file *file, loff_t start, loff_t end,
14762306a36Sopenharmony_ci		      int datasync);
14862306a36Sopenharmony_ciint hmdfs_symlink(struct inode *dir, struct dentry *dentry,
14962306a36Sopenharmony_ci		  const char *symname);
15062306a36Sopenharmony_ciint hmdfs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci/*****************************************************************************
15362306a36Sopenharmony_ci * common functions declaration
15462306a36Sopenharmony_ci *****************************************************************************/
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistatic inline struct hmdfs_dentry_info *hmdfs_d(struct dentry *dentry)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	return dentry->d_fsdata;
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_cistatic inline bool hm_isreg(uint8_t file_type)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	return (file_type == HM_REG);
16462306a36Sopenharmony_ci}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistatic inline bool hm_islnk(uint8_t file_type)
16762306a36Sopenharmony_ci{
16862306a36Sopenharmony_ci	return (file_type == HM_SYMLINK);
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistatic inline bool hm_isshare(uint8_t file_type)
17262306a36Sopenharmony_ci{
17362306a36Sopenharmony_ci	return (file_type == HM_SHARE);
17462306a36Sopenharmony_ci}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistruct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con,
17762306a36Sopenharmony_ci				struct hmdfs_lookup_ret *lookup_result,
17862306a36Sopenharmony_ci				struct inode *dir);
17962306a36Sopenharmony_cistruct hmdfs_lookup_ret *get_remote_inode_info(struct hmdfs_peer *con,
18062306a36Sopenharmony_ci					       struct dentry *dentry,
18162306a36Sopenharmony_ci					       unsigned int flags);
18262306a36Sopenharmony_civoid hmdfs_set_time(struct dentry *dentry, unsigned long time);
18362306a36Sopenharmony_cistruct inode *fill_inode_local(struct super_block *sb,
18462306a36Sopenharmony_ci			       struct inode *lower_inode, const char *name);
18562306a36Sopenharmony_cistruct inode *fill_root_inode(struct super_block *sb,
18662306a36Sopenharmony_ci			      struct hmdfs_sb_info *sbi, struct inode *lower_inode);
18762306a36Sopenharmony_cistruct inode *fill_device_inode(struct super_block *sb,
18862306a36Sopenharmony_ci				struct inode *lower_inode);
18962306a36Sopenharmony_cistruct hmdfs_lookup_ret *hmdfs_lookup_by_con(struct hmdfs_peer *con,
19062306a36Sopenharmony_ci					     struct dentry *dentry,
19162306a36Sopenharmony_ci					     struct qstr *qstr,
19262306a36Sopenharmony_ci					     unsigned int flags,
19362306a36Sopenharmony_ci					     const char *relative_path);
19462306a36Sopenharmony_cichar *hmdfs_connect_path(const char *path, const char *name);
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cichar *hmdfs_get_dentry_relative_path(struct dentry *dentry);
19762306a36Sopenharmony_cichar *hmdfs_merge_get_dentry_relative_path(struct dentry *dentry);
19862306a36Sopenharmony_cichar *hmdfs_get_dentry_absolute_path(const char *rootdir,
19962306a36Sopenharmony_ci				     const char *relative_path);
20062306a36Sopenharmony_ciint hmdfs_convert_lookup_flags(unsigned int hmdfs_flags,
20162306a36Sopenharmony_ci			       unsigned int *vfs_flags);
20262306a36Sopenharmony_cistatic inline void hmdfs_get_lower_path(struct dentry *dent, struct path *pname)
20362306a36Sopenharmony_ci{
20462306a36Sopenharmony_ci	spin_lock(&hmdfs_d(dent)->lock);
20562306a36Sopenharmony_ci	pname->dentry = hmdfs_d(dent)->lower_path.dentry;
20662306a36Sopenharmony_ci	pname->mnt = hmdfs_d(dent)->lower_path.mnt;
20762306a36Sopenharmony_ci	path_get(pname);
20862306a36Sopenharmony_ci	spin_unlock(&hmdfs_d(dent)->lock);
20962306a36Sopenharmony_ci}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic inline void hmdfs_put_lower_path(struct path *pname)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	path_put(pname);
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistatic inline void hmdfs_put_reset_lower_path(struct dentry *dent)
21762306a36Sopenharmony_ci{
21862306a36Sopenharmony_ci	struct path pname;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	spin_lock(&hmdfs_d(dent)->lock);
22162306a36Sopenharmony_ci	if (hmdfs_d(dent)->lower_path.dentry) {
22262306a36Sopenharmony_ci		pname.dentry = hmdfs_d(dent)->lower_path.dentry;
22362306a36Sopenharmony_ci		pname.mnt = hmdfs_d(dent)->lower_path.mnt;
22462306a36Sopenharmony_ci		hmdfs_d(dent)->lower_path.dentry = NULL;
22562306a36Sopenharmony_ci		hmdfs_d(dent)->lower_path.mnt = NULL;
22662306a36Sopenharmony_ci		spin_unlock(&hmdfs_d(dent)->lock);
22762306a36Sopenharmony_ci		path_put(&pname);
22862306a36Sopenharmony_ci	} else {
22962306a36Sopenharmony_ci		spin_unlock(&hmdfs_d(dent)->lock);
23062306a36Sopenharmony_ci	}
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic inline void hmdfs_set_lower_path(struct dentry *dent, struct path *pname)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	spin_lock(&hmdfs_d(dent)->lock);
23662306a36Sopenharmony_ci	hmdfs_d(dent)->lower_path.dentry = pname->dentry;
23762306a36Sopenharmony_ci	hmdfs_d(dent)->lower_path.mnt = pname->mnt;
23862306a36Sopenharmony_ci	spin_unlock(&hmdfs_d(dent)->lock);
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci/* Only reg file for HMDFS_LAYER_OTHER_* support xattr */
24262306a36Sopenharmony_cistatic inline bool hmdfs_support_xattr(struct dentry *dentry)
24362306a36Sopenharmony_ci{
24462306a36Sopenharmony_ci	struct inode *inode = d_inode(dentry);
24562306a36Sopenharmony_ci	struct hmdfs_inode_info *info = hmdfs_i(inode);
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	if (info->inode_type != HMDFS_LAYER_OTHER_LOCAL &&
24862306a36Sopenharmony_ci	    info->inode_type != HMDFS_LAYER_OTHER_REMOTE &&
24962306a36Sopenharmony_ci	    info->inode_type != HMDFS_LAYER_OTHER_MERGE &&
25062306a36Sopenharmony_ci	    info->inode_type != HMDFS_LAYER_OTHER_MERGE_CLOUD)
25162306a36Sopenharmony_ci		return false;
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	if (info->inode_type == HMDFS_LAYER_OTHER_LOCAL &&
25462306a36Sopenharmony_ci	    hm_islnk(hmdfs_d(dentry)->file_type))
25562306a36Sopenharmony_ci		return false;
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	return true;
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ciint init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry,
26162306a36Sopenharmony_ci			   int dentry_type);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci#endif
264