From 6d465455aee3c1a571fbbbf94b51453aa35ca370 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Mon, 24 Apr 2023 17:17:25 +0800 Subject: [PATCH 1/2] hmdfs: support inode write open count Signed-off-by: Qiheng Lin Change-Id: I31183c8b63705553f591c7e3370e049a6ce512ce --- fs/hmdfs/file_cloud.c | 82 ++++++++++++++++++++++++++++++++++++++++-- fs/hmdfs/file_local.c | 6 ++++ fs/hmdfs/file_merge.c | 25 +++++++++++++ fs/hmdfs/hmdfs.h | 4 +++ fs/hmdfs/hmdfs_share.h | 4 --- fs/hmdfs/inode.h | 1 + 6 files changed, 115 insertions(+), 7 deletions(-) diff --git a/fs/hmdfs/file_cloud.c b/fs/hmdfs/file_cloud.c index 47e0e3a71633..6da270b521ad 100644 --- a/fs/hmdfs/file_cloud.c +++ b/fs/hmdfs/file_cloud.c @@ -22,6 +22,7 @@ #include "hmdfs.h" #include "hmdfs_client.h" #include "hmdfs_dentryfile.h" +#include "hmdfs_dentryfile_cloud.h" #include "hmdfs_trace.h" #define DATA_CLOUD "/mnt/hmdfs/100/cloud" @@ -117,16 +118,91 @@ const struct address_space_operations hmdfs_dev_file_aops_cloud = { .set_page_dirty = NULL, }; +int analysis_dentry_file_from_cloud(struct hmdfs_sb_info *sbi, + struct file *file, struct file *handler, + struct dir_context *ctx) +{ + struct hmdfs_dentry_group_cloud *dentry_group = NULL; + loff_t pos = ctx->pos; + unsigned long dev_id = (unsigned long)((pos << 1) >> (POS_BIT_NUM - DEV_ID_BIT_NUM)); + unsigned long group_id = (unsigned long)((pos << (1 + DEV_ID_BIT_NUM)) >> + (POS_BIT_NUM - GROUP_ID_BIT_NUM)); + loff_t offset = pos & OFFSET_BIT_MASK; + int group_num = 0; + char *dentry_name = NULL; + int iterate_result = 0; + int i, j; + + dentry_group = kzalloc(sizeof(*dentry_group), GFP_KERNEL); + + if (!dentry_group) + return -ENOMEM; + + if (IS_ERR_OR_NULL(handler)) { + kfree(dentry_group); + return -ENOENT; + } + + group_num = get_dentry_group_cnt(file_inode(handler)); + dentry_name = kzalloc(DENTRY_NAME_MAX_LEN, GFP_KERNEL); + if (!dentry_name) { + kfree(dentry_group); + return -ENOMEM; + } + + for (i = group_id; i < group_num; i++) { + int ret = hmdfs_metainfo_read(sbi, handler, dentry_group, + sizeof(struct hmdfs_dentry_group_cloud), + i); + if (ret != sizeof(struct hmdfs_dentry_group_cloud)) { + hmdfs_err("read dentry group failed ret:%d", ret); + goto done; + } + + for (j = offset; j < DENTRY_PER_GROUP_CLOUD; j++) { + int len; + int file_type = DT_UNKNOWN; + bool is_continue; + + len = le16_to_cpu(dentry_group->nsl[j].namelen); + if (!test_bit_le(j, dentry_group->bitmap) || len == 0) + continue; + + memset(dentry_name, 0, DENTRY_NAME_MAX_LEN); + if (S_ISDIR(le16_to_cpu(dentry_group->nsl[j].i_mode))) + file_type = DT_DIR; + else if (S_ISREG(le16_to_cpu( + dentry_group->nsl[j].i_mode))) + file_type = DT_REG; + + strncat(dentry_name, dentry_group->filename[j], len); + pos = hmdfs_set_pos(dev_id, i, j); + is_continue = + dir_emit(ctx, dentry_name, len, + pos + INUNUMBER_START, file_type); + if (!is_continue) { + ctx->pos = pos; + iterate_result = 1; + goto done; + } + } + offset = 0; + } + +done: + kfree(dentry_name); + kfree(dentry_group); + return iterate_result; +} + static int hmdfs_iterate_cloud(struct file *file, struct dir_context *ctx) { int err = 0; loff_t start_pos = ctx->pos; - uint64_t dev_id = CLOUD_DEVICE; if (ctx->pos == -1) return 0; - ctx->pos = hmdfs_set_pos(dev_id, 0, 0); - err = analysis_dentry_file_from_con( + err = analysis_dentry_file_from_cloud( file->f_inode->i_sb->s_fs_info, file, file->private_data, ctx); if (err <= 0) diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index 20a997236ac9..140069f84d03 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -28,6 +28,7 @@ int hmdfs_file_open_local(struct inode *inode, struct file *file) struct super_block *sb = inode->i_sb; const struct cred *cred = hmdfs_sb(sb)->cred; struct hmdfs_file_info *gfi = kzalloc(sizeof(*gfi), GFP_KERNEL); + struct hmdfs_inode_info *info = hmdfs_i(inode); if (!gfi) { err = -ENOMEM; @@ -43,6 +44,8 @@ int hmdfs_file_open_local(struct inode *inode, struct file *file) } else { gfi->lower_file = lower_file; file->private_data = gfi; + if (file->f_flags & (O_RDWR | O_WRONLY)) + info->write_opened++; } out_err: return err; @@ -51,7 +54,10 @@ int hmdfs_file_open_local(struct inode *inode, struct file *file) int hmdfs_file_release_local(struct inode *inode, struct file *file) { struct hmdfs_file_info *gfi = hmdfs_f(file); + struct hmdfs_inode_info *info = hmdfs_i(inode); + if (file->f_flags & (O_RDWR | O_WRONLY)) + info->write_opened--; file->private_data = NULL; fput(gfi->lower_file); kfree(gfi); diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index e7b75b6e3e9f..7f3aa3be6c63 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -567,6 +567,27 @@ int hmdfs_file_flush_merge(struct file *file, fl_owner_t id) return 0; } +static long hmdfs_ioc_get_writeopen_cnt(struct file *filp, unsigned long arg) +{ + struct hmdfs_file_info *gfi = hmdfs_f(filp); + struct file *lower_file = gfi->lower_file; + struct inode *lower_inode = file_inode(lower_file); + + u32 wo_cnt = hmdfs_i(lower_inode)->write_opened; + + return put_user(wo_cnt, (int __user *)arg); +} + +static long hmdfs_file_ioctl_merge(struct file *filp, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case HMDFS_IOC_GET_WRITEOPEN_CNT: + return hmdfs_ioc_get_writeopen_cnt(filp, arg); + default: + return -ENOTTY; + } +} + /* Transparent transmission of parameters to device_view level, * so file operations are same as device_view local operations. */ @@ -580,6 +601,10 @@ const struct file_operations hmdfs_file_fops_merge = { .flush = hmdfs_file_flush_merge, .release = hmdfs_file_release_local, .fsync = hmdfs_fsync_local, + .unlocked_ioctl = hmdfs_file_ioctl_merge, +#ifdef CONFIG_COMPAT + .compat_ioctl = hmdfs_file_ioctl_merge, +#endif .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, }; diff --git a/fs/hmdfs/hmdfs.h b/fs/hmdfs/hmdfs.h index fd964ecf2e5d..208de9f28cbb 100644 --- a/fs/hmdfs/hmdfs.h +++ b/fs/hmdfs/hmdfs.h @@ -27,6 +27,10 @@ #define hmdfs_time_add timespec_add #endif +#define HMDFS_IOC 0xf2 +#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct hmdfs_share_control) +#define HMDFS_IOC_GET_WRITEOPEN_CNT _IOR(HMDFS_IOC, 2, __u32) + #define HMDFS_PAGE_SIZE 4096 #define HMDFS_PAGE_OFFSET 12 diff --git a/fs/hmdfs/hmdfs_share.h b/fs/hmdfs/hmdfs_share.h index 3c055805bd6d..2db8c3a4c6d2 100644 --- a/fs/hmdfs/hmdfs_share.h +++ b/fs/hmdfs/hmdfs_share.h @@ -18,10 +18,6 @@ #define HMDFS_SHARE_ITEM_TIMEOUT_S 120 #define HMDFS_SHARE_ITEMS_MAX 128 -#define HMDFS_IOC 0xf2 -#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, \ - struct hmdfs_share_control) - #define SHARE_RESERVED_DIR ".share" #define SHARE_ALL_DEVICE "0" diff --git a/fs/hmdfs/inode.h b/fs/hmdfs/inode.h index 9619b5bb2792..09f4209cc90f 100644 --- a/fs/hmdfs/inode.h +++ b/fs/hmdfs/inode.h @@ -74,6 +74,7 @@ struct hmdfs_inode_info { unsigned long fid_flags; wait_queue_head_t fid_wq; __u8 inode_type; // deprecated: use ino system instead + __u32 write_opened; /* writeback list */ struct list_head wb_list; -- Gitee From 6458d6d7fb852403a4f1b8e0eabc2c60dc4aae41 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Wed, 26 Apr 2023 10:06:11 +0800 Subject: [PATCH 2/2] hmdfs: use atomic write_opened Signed-off-by: Qiheng Lin Change-Id: I22a181a2e6df70c30781f841f1a184dbbc8c2452 --- fs/hmdfs/file_local.c | 4 ++-- fs/hmdfs/file_merge.c | 5 +---- fs/hmdfs/inode.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index 140069f84d03..c4649bd20476 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -45,7 +45,7 @@ int hmdfs_file_open_local(struct inode *inode, struct file *file) gfi->lower_file = lower_file; file->private_data = gfi; if (file->f_flags & (O_RDWR | O_WRONLY)) - info->write_opened++; + atomic_inc(&info->write_opened); } out_err: return err; @@ -57,7 +57,7 @@ int hmdfs_file_release_local(struct inode *inode, struct file *file) struct hmdfs_inode_info *info = hmdfs_i(inode); if (file->f_flags & (O_RDWR | O_WRONLY)) - info->write_opened--; + atomic_dec(&info->write_opened); file->private_data = NULL; fput(gfi->lower_file); kfree(gfi); diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index 7f3aa3be6c63..0b45586b39ca 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -573,7 +573,7 @@ static long hmdfs_ioc_get_writeopen_cnt(struct file *filp, unsigned long arg) struct file *lower_file = gfi->lower_file; struct inode *lower_inode = file_inode(lower_file); - u32 wo_cnt = hmdfs_i(lower_inode)->write_opened; + u32 wo_cnt = atomic_read(&(hmdfs_i(lower_inode))->write_opened); return put_user(wo_cnt, (int __user *)arg); } @@ -602,9 +602,6 @@ const struct file_operations hmdfs_file_fops_merge = { .release = hmdfs_file_release_local, .fsync = hmdfs_fsync_local, .unlocked_ioctl = hmdfs_file_ioctl_merge, -#ifdef CONFIG_COMPAT - .compat_ioctl = hmdfs_file_ioctl_merge, -#endif .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, }; diff --git a/fs/hmdfs/inode.h b/fs/hmdfs/inode.h index 09f4209cc90f..d2d02e9b2999 100644 --- a/fs/hmdfs/inode.h +++ b/fs/hmdfs/inode.h @@ -74,7 +74,7 @@ struct hmdfs_inode_info { unsigned long fid_flags; wait_queue_head_t fid_wq; __u8 inode_type; // deprecated: use ino system instead - __u32 write_opened; + atomic_t write_opened; /* writeback list */ struct list_head wb_list; -- Gitee