diff --git a/fs/hmdfs/file_cloud.c b/fs/hmdfs/file_cloud.c index 47e0e3a71633534fbb12daac144edf66cfe826f8..6da270b521adcfe634f9281d68c24d515892b913 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 20a997236ac98d680ba80559332fa92dc5b16e4f..c4649bd20476633b9f5b3daca325b1f7d877d03f 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)) + atomic_inc(&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)) + 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 e7b75b6e3e9f1a97d5b0f499730cf0a2b33d7444..0b45586b39ca4d66924360a14ee1ed65420f6ee9 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 = atomic_read(&(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,7 @@ 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, .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 fd964ecf2e5dc1da740ca577c46deb141abd83f6..208de9f28cbb6fc55c2a1a5b5800bce900852dc2 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 3c055805bd6dd1327be47790a7f036cf1d1cb5b8..2db8c3a4c6d28b0f43a295c1c9476e6557c72f57 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 9619b5bb279249302410fb840167be52de2128fd..d2d02e9b299924524c657b796c47ea41667e0bbb 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 + atomic_t write_opened; /* writeback list */ struct list_head wb_list;