From 19b3f879fb600c4bad5a933b2ca910ca938470bb Mon Sep 17 00:00:00 2001 From: Jingyao Zeng Date: Tue, 18 Mar 2025 14:15:03 +0800 Subject: [PATCH 1/3] feat: add open-read and drop page cache push Signed-off-by: Jingyao Zeng --- fs/hmdfs/comm/device_node.c | 18 +- fs/hmdfs/comm/message_verify.c | 40 +- fs/hmdfs/comm/protocol.h | 21 +- fs/hmdfs/comm/socket_adapter.c | 3 + fs/hmdfs/file_local.c | 20 +- fs/hmdfs/file_merge.c | 62 ++- fs/hmdfs/file_remote.c | 83 ++- fs/hmdfs/hmdfs.h | 2 - fs/hmdfs/hmdfs_client.c | 78 ++- fs/hmdfs/hmdfs_client.h | 4 +- fs/hmdfs/hmdfs_dentryfile.c | 112 +++- fs/hmdfs/hmdfs_dentryfile.h | 3 + fs/hmdfs/hmdfs_device_view.h | 9 +- fs/hmdfs/hmdfs_server.c | 979 +++++++++++++++++++++------------ fs/hmdfs/hmdfs_server.h | 11 + fs/hmdfs/inode.h | 3 + fs/hmdfs/inode_local.c | 4 +- fs/hmdfs/main.c | 4 + 18 files changed, 1065 insertions(+), 391 deletions(-) diff --git a/fs/hmdfs/comm/device_node.c b/fs/hmdfs/comm/device_node.c index 59016ecaf931..63b8a619d980 100644 --- a/fs/hmdfs/comm/device_node.c +++ b/fs/hmdfs/comm/device_node.c @@ -1332,6 +1332,7 @@ HMDFS_CMD_ATTR(rename, F_RENAME); HMDFS_CMD_ATTR(setattr, F_SETATTR); HMDFS_CMD_ATTR(statfs, F_STATFS); HMDFS_CMD_ATTR(drop_push, F_DROP_PUSH); +HMDFS_CMD_ATTR(drop_page_push, F_DROP_PAGE_PUSH); HMDFS_CMD_ATTR(getattr, F_GETATTR); HMDFS_CMD_ATTR(fsync, F_FSYNC); HMDFS_CMD_ATTR(syncfs, F_SYNCFS); @@ -1342,17 +1343,16 @@ HMDFS_CMD_ATTR(listxattr, F_LISTXATTR); #define ATTR_LIST(_name) (&hmdfs_attr_##_name.attr) static struct attribute *sbi_timeout_attrs[] = { - ATTR_LIST(open), ATTR_LIST(release), + ATTR_LIST(open), ATTR_LIST(release), ATTR_LIST(readpage), ATTR_LIST(writepage), - ATTR_LIST(iterate), ATTR_LIST(rmdir), - ATTR_LIST(unlink), ATTR_LIST(rename), - ATTR_LIST(setattr), - ATTR_LIST(statfs), ATTR_LIST(drop_push), - ATTR_LIST(getattr), ATTR_LIST(fsync), - ATTR_LIST(syncfs), ATTR_LIST(getxattr), + ATTR_LIST(iterate), ATTR_LIST(rmdir), + ATTR_LIST(unlink), ATTR_LIST(rename), + ATTR_LIST(setattr), ATTR_LIST(statfs), + ATTR_LIST(drop_push), ATTR_LIST(drop_page_push), + ATTR_LIST(getattr), ATTR_LIST(fsync), + ATTR_LIST(syncfs), ATTR_LIST(getxattr), ATTR_LIST(setxattr), ATTR_LIST(listxattr), - NULL -}; + NULL}; static const struct sysfs_ops sbi_cmd_sysfs_ops = { .show = cmd_timeout_show, diff --git a/fs/hmdfs/comm/message_verify.c b/fs/hmdfs/comm/message_verify.c index 4c593390778c..b3ae61a2d267 100644 --- a/fs/hmdfs/comm/message_verify.c +++ b/fs/hmdfs/comm/message_verify.c @@ -27,6 +27,7 @@ void hmdfs_message_verify_init(void) need_response[F_RELEASE] = false; need_response[F_CONNECT_REKEY] = false; need_response[F_DROP_PUSH] = false; + need_response[F_DROP_PAGE_PUSH] = false; for (flag = 0; flag < C_FLAG_SIZE; flag++) { for (cmd = 0; cmd < F_SIZE; cmd++) { @@ -269,6 +270,13 @@ void hmdfs_message_verify_init(void) sizeof(struct drop_push_request) + PATH_MAX + 1; message_length[C_REQUEST][F_DROP_PUSH][HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_RANGE; + + message_length[C_REQUEST][F_DROP_PAGE_PUSH][HMDFS_MESSAGE_MIN_INDEX] = + sizeof(struct drop_page_push_request); + message_length[C_REQUEST][F_DROP_PAGE_PUSH][HMDFS_MESSAGE_MAX_INDEX] = + sizeof(struct drop_page_push_request) + PATH_MAX + 1; + message_length[C_REQUEST][F_DROP_PAGE_PUSH][HMDFS_MESSAGE_LEN_JUDGE_INDEX] = + MESSAGE_LEN_JUDGE_RANGE; } static int is_str_msg_valid(char *msg, int str_len[], size_t str_num) @@ -856,6 +864,34 @@ static int hmdfs_drop_push_verify(int flag, size_t msg_len, void *msg) return 0; } +static int verify_drop_page_push_req(size_t msg_len, void *msg) +{ + struct drop_page_push_request *req = msg; + int str_len[] = {req->path_len}; + + if (req->path_len < 0 || req->path_len >= PATH_MAX) + return -EINVAL; + + if (msg_len != sizeof(*req) + req->path_len + 1) + return -EINVAL; + + if (is_str_msg_valid(req->buf, str_len, sizeof(str_len) / sizeof(int))) + return -EINVAL; + + return 0; +} + +static int hmdfs_drop_page_push_verify(int flag, size_t msg_len, void *msg) +{ + if (!msg || !msg_len) + return 0; + + if (flag == C_REQUEST) + return verify_drop_page_push_req(msg_len, msg); + + return 0; +} + typedef int (*hmdfs_message_verify_func)(int, size_t, void *); static const hmdfs_message_verify_func message_verify[F_SIZE] = { @@ -871,6 +907,7 @@ static const hmdfs_message_verify_func message_verify[F_SIZE] = { [F_SETATTR] = hmdfs_setattr_verify, [F_STATFS] = hmdfs_statfs_verify, [F_DROP_PUSH] = hmdfs_drop_push_verify, + [F_DROP_PAGE_PUSH] = hmdfs_drop_page_push_verify, [F_GETATTR] = hmdfs_getattr_verify, [F_GETXATTR] = hmdfs_getxattr_verify, [F_SETXATTR] = hmdfs_setxattr_verify, @@ -912,8 +949,7 @@ static void handle_bad_message(struct hmdfs_peer *con, bool is_reserved_command(int command) { if ((command >= F_RESERVED_1 && command <= F_RESERVED_4) || - command == F_RESERVED_5 || command == F_RESERVED_6 || - command == F_RESERVED_7 || command == F_RESERVED_8) + command == F_RESERVED_5 || command == F_RESERVED_7 || command == F_RESERVED_8) return true; return false; } diff --git a/fs/hmdfs/comm/protocol.h b/fs/hmdfs/comm/protocol.h index beaa5adf4ba1..aebb6c7dc4b2 100644 --- a/fs/hmdfs/comm/protocol.h +++ b/fs/hmdfs/comm/protocol.h @@ -23,6 +23,8 @@ struct hmdfs_cmd { #define HMDFS_MSG_MAGIC 0xF7 #define HMDFS_MAX_MESSAGE_LEN (8 * 1024 * 1024) +#define HMDFS_PAGE_SIZE 4096 + struct hmdfs_head_cmd { __u8 magic; __u8 version; @@ -151,7 +153,8 @@ enum DFS_VERSION { enum CMD_FLAG { C_REQUEST = 0, C_RESPONSE = 1, C_FLAG_SIZE }; -enum FILE_CMD { +enum FILE_CMD +{ F_OPEN = 0, F_RELEASE = 1, F_READPAGE = 2, @@ -171,7 +174,7 @@ enum FILE_CMD { F_STATFS = 16, F_CONNECT_REKEY = 17, F_DROP_PUSH = 18, - F_RESERVED_6 = 19, + F_DROP_PAGE_PUSH = 19, F_GETATTR = 20, F_FSYNC = 21, F_SYNCFS = 22, @@ -204,6 +207,8 @@ struct open_response { __le64 stable_ctime; __le32 stable_ctime_nsec; __le64 ichange_count; + __u8 read_success; + __u8 page[HMDFS_PAGE_SIZE]; } __packed; enum hmdfs_open_flags { @@ -332,6 +337,18 @@ struct drop_push_request { char path[0]; } __packed; +struct drop_page_push_request{ + __le64 file_size; + __le64 ctime; + __le32 ctime_nsec; + __le64 mtime; + __le32 mtime_nsec; + __le64 stable_ctime; + __le32 stable_ctime_nsec; + __le32 path_len; + char buf[0]; +} __packed; + struct setattr_request { __le64 size; __le32 valid; diff --git a/fs/hmdfs/comm/socket_adapter.c b/fs/hmdfs/comm/socket_adapter.c index b9f35b9e1626..6b4bcde48d7f 100644 --- a/fs/hmdfs/comm/socket_adapter.c +++ b/fs/hmdfs/comm/socket_adapter.c @@ -43,6 +43,7 @@ static const request_callback s_recv_callbacks[F_SIZE] = { [F_SETATTR] = hmdfs_server_setattr, [F_STATFS] = hmdfs_server_statfs, [F_DROP_PUSH] = hmdfs_server_get_drop_push, + [F_DROP_PAGE_PUSH] = hmdfs_server_get_drop_page_push, [F_GETATTR] = hmdfs_server_getattr, [F_FSYNC] = hmdfs_server_fsync, [F_SYNCFS] = hmdfs_server_syncfs, @@ -835,6 +836,7 @@ static int hmdfs_request_recv(struct hmdfs_peer *con, case F_STATFS: case F_CONNECT_REKEY: case F_DROP_PUSH: + case F_DROP_PAGE_PUSH: case F_GETATTR: case F_FSYNC: case F_SYNCFS: @@ -1045,6 +1047,7 @@ static int hmdfs_response_recv(struct hmdfs_peer *con, case F_STATFS: case F_CONNECT_REKEY: case F_DROP_PUSH: + case F_DROP_PAGE_PUSH: case F_GETATTR: case F_FSYNC: case F_SYNCFS: diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index 41f65cfa4184..96072d260aa9 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -64,6 +64,15 @@ int hmdfs_file_release_local(struct inode *inode, struct file *file) if (file->f_flags & (O_RDWR | O_WRONLY)) atomic_dec(&info->write_opened); + + spin_lock(&info->modify_lock); + if (info->modified) + { + hmdfs_drop_remote_cache_pages(file_dentry(file)); + info->modified = false; + } + spin_unlock(&info->modify_lock); + file->private_data = NULL; fput(gfi->lower_file); kfree(gfi); @@ -112,6 +121,7 @@ static ssize_t hmdfs_local_read_iter(struct kiocb *iocb, struct iov_iter *iter) static void hmdfs_file_modified(struct file *file) { struct inode *inode = file_inode(file); + struct hmdfs_inode_info *info = hmdfs_i(inode); struct dentry *dentry = file_dentry(file); struct file *lower_file = hmdfs_f(file)->lower_file; struct inode *lower_inode = file_inode(lower_file); @@ -123,10 +133,14 @@ static void hmdfs_file_modified(struct file *file) if (!hmdfs_i_merge(hmdfs_i(inode))) update_inode_to_dentry(dentry, inode); + + spin_lock(&info->modify_lock); + info->modified = true; + spin_unlock(&info->modify_lock); } -ssize_t hmdfs_do_write_iter(struct file *file, struct iov_iter *iter, - loff_t *ppos) +ssize_t hmdfs_do_write_iter_local(struct file *file, struct iov_iter *iter, + loff_t *ppos) { ssize_t ret; struct file *lower_file = hmdfs_f(file)->lower_file; @@ -154,7 +168,7 @@ ssize_t hmdfs_do_write_iter(struct file *file, struct iov_iter *iter, ssize_t hmdfs_local_write_iter(struct kiocb *iocb, struct iov_iter *iter) { - return hmdfs_do_write_iter(iocb->ki_filp, iter, &iocb->ki_pos); + return hmdfs_do_write_iter_local(iocb->ki_filp, iter, &iocb->ki_pos); } int hmdfs_fsync_local(struct file *file, loff_t start, loff_t end, int datasync) diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index 8952674a23d4..3306e781b72c 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -532,9 +532,52 @@ static ssize_t hmdfs_merge_read_iter(struct kiocb *iocb, struct iov_iter *iter) return hmdfs_do_read_iter(iocb->ki_filp, iter, &iocb->ki_pos); } +static void hmdfs_file_modified(struct file *file) +{ + struct inode *inode = file_inode(file); + struct dentry *dentry = file_dentry(file); + struct file *lower_file = hmdfs_f(file)->lower_file; + struct inode *lower_inode = file_inode(lower_file); + + inode->i_atime = lower_inode->i_atime; + inode->i_ctime = lower_inode->i_ctime; + inode->i_mtime = lower_inode->i_mtime; + i_size_write(inode, i_size_read(lower_inode)); + + if (!hmdfs_i_merge(hmdfs_i(inode))) + update_inode_to_dentry(dentry, inode); +} + +ssize_t hmdfs_do_write_iter_merge(struct file *file, struct iov_iter *iter, + loff_t *ppos) +{ + ssize_t ret; + struct file *lower_file = hmdfs_f(file)->lower_file; + struct inode *inode = file_inode(file); + + if (!iov_iter_count(iter)) + return 0; + + inode_lock(inode); + + ret = file_remove_privs(file); + if (ret) + goto out_unlock; + + file_start_write(lower_file); + ret = vfs_iter_write(lower_file, iter, ppos, 0); + file_end_write(lower_file); + + hmdfs_file_modified(file); + +out_unlock: + inode_unlock(inode); + return ret; +} + ssize_t hmdfs_merge_write_iter(struct kiocb *iocb, struct iov_iter *iter) { - return hmdfs_do_write_iter(iocb->ki_filp, iter, &iocb->ki_pos); + return hmdfs_do_write_iter_merge(iocb->ki_filp, iter, &iocb->ki_pos); } int hmdfs_file_open_merge(struct inode *inode, struct file *file) @@ -575,6 +618,19 @@ int hmdfs_file_open_merge(struct inode *inode, struct file *file) return err; } +int hmdfs_file_release_merge(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); + return 0; +} + int hmdfs_file_flush_merge(struct file *file, fl_owner_t id) { struct hmdfs_file_info *gfi = hmdfs_f(file); @@ -827,9 +883,9 @@ const struct file_operations hmdfs_file_fops_merge = { .mmap = hmdfs_file_mmap_local, .open = hmdfs_file_open_merge, .flush = hmdfs_file_flush_merge, - .release = hmdfs_file_release_local, + .release = hmdfs_file_release_merge, .fsync = hmdfs_fsync_local, - .unlocked_ioctl = hmdfs_file_ioctl_merge, + .unlocked_ioctl = hmdfs_file_ioctl_merge, .compat_ioctl = hmdfs_file_ioctl_merge, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, diff --git a/fs/hmdfs/file_remote.c b/fs/hmdfs/file_remote.c index e3c012b73a83..36e42bb7637a 100644 --- a/fs/hmdfs/file_remote.c +++ b/fs/hmdfs/file_remote.c @@ -154,7 +154,16 @@ static int hmdfs_open_final_remote(struct hmdfs_inode_info *info, return 0; } -int hmdfs_do_open_remote(struct file *file, bool keep_cache) +static void hmdfs_set_page_content(struct page *page, const void *data) +{ + void *addr; + addr = kmap(page); + memcpy(addr, data, HMDFS_PAGE_SIZE); + SetPageUptodate(page); + kunmap(page); +} + +int hmdfs_do_open_remote(struct inode *inode, struct file *file, bool keep_cache) { struct hmdfs_inode_info *info = hmdfs_i(file_inode(file)); struct hmdfs_peer *conn = info->conn; @@ -175,6 +184,26 @@ int hmdfs_do_open_remote(struct file *file, bool keep_cache) } err = hmdfs_open_final_remote(info, &open_ret, file, keep_cache); + if (err) + { + hmdfs_err("hmdfs_open_final_remote return failed with %d", err); + goto out_free; + } + + struct page *page = grab_cache_page(inode->i_mapping, 0); + if (!IS_ERR(page)) + { + if (open_ret.read_success) + { + hmdfs_set_page_content(page, open_ret.page); + unlock_page(page); + } + else + { + unlock_page(page); + put_page(page); + } + } out_free: kfree(send_buf); @@ -247,7 +276,7 @@ static int hmdfs_remote_file_reopen(struct hmdfs_inode_info *info, */ if (fid.id != HMDFS_INODE_INVALID_FILE_ID) hmdfs_send_close(conn, &fid); - err = hmdfs_do_open_remote(filp, true); + err = hmdfs_do_open_remote(inode, filp, true); inode_unlock(inode); spin_lock(&info->fid_lock); @@ -337,10 +366,49 @@ int hmdfs_file_open_remote(struct inode *inode, struct file *file) int err = 0; inode_lock(inode); + + // NB: we only consider small file (size <= 1 KiB) here, otherwise we may need handle reading uncached pages when the file is not actually opened if (kref_read(ref) == 0) { - err = hmdfs_do_open_remote(file, false); - if (err == 0) - kref_init(ref); + // If the file is opened with intent to be modified, then we must communicate with the file holder + if ((file->f_flags & O_ACCMODE) == O_RDONLY) + { + if (info->need_reopen) + { + err = hmdfs_do_open_remote(inode, file, false); + if (err == 0) + { + kref_init(ref); + info->need_reopen = false; + } + } + else + { + if (info->writecache_expire && hmdfs_remote_write_cache_expired(info)) + { + // different from above situation, here we set writecache_expire to 0, and truncate the inode page + // because we can omit the repeated judgement in hmdfs_open_final_remote + info->writecache_expire = 0; + truncate_inode_pages(inode->i_mapping, 0); + err = hmdfs_do_open_remote(inode, file, false); + if (err == 0) + kref_init(ref); + } + else + { + atomic64_set(&info->write_counter, 0); + info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE; + } + } + } + else + { + err = hmdfs_do_open_remote(inode, file, false); + if (err == 0) + { + kref_init(ref); + info->need_reopen = false; + } + } } else { kref_get(ref); } @@ -426,7 +494,10 @@ int hmdfs_file_release_remote(struct inode *inode, struct file *file) hmdfs_remote_del_wr_opened_inode(info->conn, info); inode_lock(inode); - kref_put(&info->ref, hmdfs_do_close_remote); + if (kref_read(&info->ref) > 0) + { + kref_put(&info->ref, hmdfs_do_close_remote); + } hmdfs_remote_keep_writecache(inode, file); inode_unlock(inode); diff --git a/fs/hmdfs/hmdfs.h b/fs/hmdfs/hmdfs.h index c9940693f3e7..a7d80320f438 100644 --- a/fs/hmdfs/hmdfs.h +++ b/fs/hmdfs/hmdfs.h @@ -32,8 +32,6 @@ #define HMDFS_IOC_GET_WRITEOPEN_CNT _IOR(HMDFS_IOC, 2, __u32) #define HMDFS_IOC_GET_DST_PATH _IOR(HMDFS_IOC, 3, __u32) - -#define HMDFS_PAGE_SIZE 4096 #define HMDFS_PAGE_OFFSET 12 /* max xattr value size, not include '\0' */ diff --git a/fs/hmdfs/hmdfs_client.c b/fs/hmdfs/hmdfs_client.c index 827d6b533f66..17ee4b8bca06 100644 --- a/fs/hmdfs/hmdfs_client.c +++ b/fs/hmdfs/hmdfs_client.c @@ -29,8 +29,30 @@ static inline void free_sm_outbuf(struct hmdfs_send_command *sm) sm->out_buf = NULL; } +static struct hmdfs_time_t msec_to_timespec(unsigned int msec) +{ + struct hmdfs_time_t timespec = { + .tv_sec = msec / MSEC_PER_SEC, + .tv_nsec = (msec % MSEC_PER_SEC) * NSEC_PER_MSEC, + }; + + return timespec; +} + +static struct hmdfs_time_t hmdfs_current_kernel_time(void) +{ + struct hmdfs_time_t time; + +#if KERNEL_VERSION(4, 18, 0) < LINUX_VERSION_CODE + ktime_get_coarse_real_ts64(&time); +#else + time = current_kernel_time(); +#endif + return time; +} + int hmdfs_send_open(struct hmdfs_peer *con, const char *send_buf, - __u8 file_type, struct hmdfs_open_ret *open_ret) + __u8 file_type, struct hmdfs_open_ret *open_ret) { int ret; int path_len = strlen(send_buf); @@ -69,6 +91,9 @@ int hmdfs_send_open(struct hmdfs_peer *con, const char *send_buf, open_ret->remote_ctime.tv_nsec = le32_to_cpu(resp->ctime_nsec); open_ret->stable_ctime.tv_sec = le64_to_cpu(resp->stable_ctime); open_ret->stable_ctime.tv_nsec = le32_to_cpu(resp->stable_ctime_nsec); + open_ret->read_success = resp->read_success; + if (open_ret->read_success) + memcpy(open_ret->page, resp->page, HMDFS_PAGE_SIZE); out: free_sm_outbuf(&sm); @@ -1048,6 +1073,57 @@ void hmdfs_send_drop_push(struct hmdfs_peer *con, const char *path) kfree(dp_req); } +void hmdfs_send_drop_page_push(struct hmdfs_peer *con, const char *send_buf, struct inode *inode) +{ + int path_len = strlen(send_buf); + size_t send_len = sizeof(struct drop_page_push_request) + path_len + 1; + struct drop_page_push_request *dpp_req = kzalloc(send_len, GFP_KERNEL); + struct hmdfs_send_command sm = { + .data = dpp_req, + .len = send_len, + .out_buf = NULL, + .local_filp = NULL, + }; + + struct hmdfs_time_t current_time = hmdfs_current_kernel_time(); + struct hmdfs_time_t ctime = inode->i_ctime; + struct hmdfs_time_t precision = msec_to_timespec(con->sbi->dcache_precision); + + loff_t size = i_size_read(inode); + + hmdfs_init_cmd(&sm.operations, F_DROP_PAGE_PUSH); + if (!dpp_req) + return; + + dpp_req->file_size = cpu_to_le64(size); + dpp_req->ctime = cpu_to_le64(ctime.tv_sec); + dpp_req->ctime_nsec = cpu_to_le32(ctime.tv_nsec); + + precision = hmdfs_time_add(ctime, precision); + if (hmdfs_time_compare(¤t_time, &ctime) < 0) + { + dpp_req->stable_ctime = cpu_to_le64(0); + dpp_req->stable_ctime_nsec = cpu_to_le32(0); + } + else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && + hmdfs_time_compare(¤t_time, &precision) < 0) + { + dpp_req->stable_ctime = dpp_req->ctime; + dpp_req->stable_ctime_nsec = dpp_req->ctime_nsec; + } + else + { + dpp_req->stable_ctime = cpu_to_le64(precision.tv_sec); + dpp_req->stable_ctime_nsec = cpu_to_le32(precision.tv_nsec); + } + + dpp_req->path_len = cpu_to_le32(path_len); + strcpy(dpp_req->buf, send_buf); + + hmdfs_sendmessage_request(con, &sm); + kfree(dpp_req); +} + static void *hmdfs_get_msg_next(struct hmdfs_peer *peer, int *id) { struct hmdfs_msg_idr_head *head = NULL; diff --git a/fs/hmdfs/hmdfs_client.h b/fs/hmdfs/hmdfs_client.h index ab2867dca457..e85e82c11a5e 100644 --- a/fs/hmdfs/hmdfs_client.h +++ b/fs/hmdfs/hmdfs_client.h @@ -18,6 +18,8 @@ struct hmdfs_open_ret { __u64 ino; struct hmdfs_time_t remote_ctime; struct hmdfs_time_t stable_ctime; + __u8 read_success; + __u8 page[HMDFS_PAGE_SIZE]; }; struct hmdfs_writepage_context { @@ -90,7 +92,7 @@ void hmdfs_client_writepage_done(struct hmdfs_inode_info *info, struct hmdfs_writepage_context *ctx); int hmdfs_send_open(struct hmdfs_peer *con, const char *send_buf, - __u8 file_type, struct hmdfs_open_ret *open_ret); + __u8 file_type, struct hmdfs_open_ret *open_ret); void hmdfs_send_close(struct hmdfs_peer *con, const struct hmdfs_fid *fid); int hmdfs_send_fsync(struct hmdfs_peer *con, const struct hmdfs_fid *fid, __s64 start, __s64 end, __s32 datasync); diff --git a/fs/hmdfs/hmdfs_dentryfile.c b/fs/hmdfs/hmdfs_dentryfile.c index dc8b7a74f9a7..e42cbe436c3d 100644 --- a/fs/hmdfs/hmdfs_dentryfile.c +++ b/fs/hmdfs/hmdfs_dentryfile.c @@ -212,6 +212,13 @@ static char *hmdfs_dentry_path_raw(struct dentry *d, char *buf, int buflen) read_seqbegin_or_lock(&rename_lock, &seq); while (di->dentry_type != hmdfs_root_dentry_type) { struct dentry *parent = dentry->d_parent; + /* Not sure whether it should be this */ + // if (!parent) + // { + // hmdfs_err("parent is NULL"); + // error = -EINVAL; + // break; + // } prefetch(parent); error = prepend_name(&end, &len, &dentry->d_name); @@ -2326,6 +2333,8 @@ void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path) int err = 0; struct remotecache_item *item = NULL; struct remotecache_item *item_temp = NULL; + // This path is local view + // i.e. /mnt/hmdfs//account/device_view/local/data// struct path path, root_path; struct hmdfs_dentry_info *d_info = NULL; @@ -2347,11 +2356,11 @@ void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path) } /* find duplicate con */ - mutex_lock(&d_info->remote_cache_list_lock); + spin_lock(&d_info->remote_cache_list_lock); list_for_each_entry_safe(item, item_temp, &(d_info->remote_cache_list_head), list) { if (item->con->device_id == con->device_id) { - mutex_unlock(&d_info->remote_cache_list_lock); + spin_unlock(&d_info->remote_cache_list_lock); goto out; } } @@ -2359,14 +2368,14 @@ void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path) item = kzalloc(sizeof(*item), GFP_KERNEL); if (!item) { err = -ENOMEM; - mutex_unlock(&d_info->remote_cache_list_lock); + spin_unlock(&d_info->remote_cache_list_lock); goto out; } item->con = con; item->drop_flag = 0; list_add(&(item->list), &(d_info->remote_cache_list_head)); - mutex_unlock(&d_info->remote_cache_list_lock); + spin_unlock(&d_info->remote_cache_list_lock); out: path_put(&path); @@ -2374,6 +2383,41 @@ void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path) path_put(&root_path); } +void hmdfs_add_remote_page_cache_list(struct hmdfs_peer *con, struct file *file) +{ + struct remotecache_item *item = NULL; + struct remotecache_item *item_temp = NULL; + struct hmdfs_dentry_info *d_info = NULL; + + d_info = hmdfs_d(file->f_path.dentry); + if (!d_info) + return; + + /* find duplicate con */ + spin_lock(&d_info->remote_cache_list_lock); + list_for_each_entry_safe(item, item_temp, + &(d_info->remote_cache_list_head), list) + { + if (item->con->device_id == con->device_id) + { + spin_unlock(&d_info->remote_cache_list_lock); + return; + } + } + + item = kzalloc(sizeof(*item), GFP_KERNEL); + if (!item) + { + spin_unlock(&d_info->remote_cache_list_lock); + return; + } + + item->con = con; + item->drop_flag = 0; + list_add(&(item->list), &(d_info->remote_cache_list_head)); + spin_unlock(&d_info->remote_cache_list_lock); +} + int hmdfs_drop_remote_cache_dents(struct dentry *dentry) { struct path lower_path; @@ -2411,20 +2455,64 @@ int hmdfs_drop_remote_cache_dents(struct dentry *dentry) hmdfs_err("get dentry relative path failed"); return 0; } - mutex_lock(&d_info->remote_cache_list_lock); + spin_lock(&d_info->remote_cache_list_lock); list_for_each_entry_safe(item, item_temp, &(d_info->remote_cache_list_head), list) { if (item->drop_flag) { item->drop_flag = 0; continue; } - mutex_unlock(&d_info->remote_cache_list_lock); + spin_unlock(&d_info->remote_cache_list_lock); hmdfs_send_drop_push(item->con, relative_path); - mutex_lock(&d_info->remote_cache_list_lock); + spin_lock(&d_info->remote_cache_list_lock); list_del(&item->list); kfree(item); } - mutex_unlock(&d_info->remote_cache_list_lock); + spin_unlock(&d_info->remote_cache_list_lock); + + kfree(relative_path); + return 0; +} + +int hmdfs_drop_remote_cache_pages(struct dentry *dentry) +{ + struct remotecache_item *item = NULL; + struct remotecache_item *item_temp = NULL; + struct hmdfs_dentry_info *d_info = NULL; + char *relative_path = NULL; + + if (!dentry) + { + hmdfs_err("dentry null and return"); + return 0; + } + + d_info = hmdfs_d(dentry); + if (!d_info) + { + hmdfs_err("d_info null and return"); + return 0; + } + relative_path = hmdfs_get_dentry_relative_path(dentry); + if (!relative_path) + { + hmdfs_err("get dentry relative path failed"); + return 0; + } + spin_lock(&d_info->remote_cache_list_lock); + list_for_each_entry_safe(item, item_temp, + &(d_info->remote_cache_list_head), list) + { + if (item->drop_flag == 1) + { + item->drop_flag = 0; + continue; + } + spin_unlock(&d_info->remote_cache_list_lock); + hmdfs_send_drop_page_push(item->con, relative_path, dentry->d_inode); + spin_lock(&d_info->remote_cache_list_lock); + } + spin_unlock(&d_info->remote_cache_list_lock); kfree(relative_path); return 0; @@ -2479,14 +2567,14 @@ void hmdfs_mark_drop_flag(uint64_t device_id, struct dentry *dentry) return; } - mutex_lock(&d_info->remote_cache_list_lock); + spin_lock(&d_info->remote_cache_list_lock); list_for_each_entry(item, &(d_info->remote_cache_list_head), list) { if (item->con->device_id == device_id) { item->drop_flag = 1; break; } } - mutex_unlock(&d_info->remote_cache_list_lock); + spin_unlock(&d_info->remote_cache_list_lock); } void hmdfs_clear_drop_flag(struct dentry *dentry) @@ -2505,12 +2593,12 @@ void hmdfs_clear_drop_flag(struct dentry *dentry) return; } - mutex_lock(&d_info->remote_cache_list_lock); + spin_lock(&d_info->remote_cache_list_lock); list_for_each_entry(item, &(d_info->remote_cache_list_head), list) { if (item->drop_flag) item->drop_flag = 0; } - mutex_unlock(&d_info->remote_cache_list_lock); + spin_unlock(&d_info->remote_cache_list_lock); } #define DUSTBIN_SUFFIX ".hwbk" diff --git a/fs/hmdfs/hmdfs_dentryfile.h b/fs/hmdfs/hmdfs_dentryfile.h index b3907ce1b86e..c696ff6cd653 100644 --- a/fs/hmdfs/hmdfs_dentryfile.h +++ b/fs/hmdfs/hmdfs_dentryfile.h @@ -211,6 +211,7 @@ struct clearcache_item { }; void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path); +void hmdfs_add_remote_page_cache_list(struct hmdfs_peer *con, struct file *file); struct remotecache_item { struct hmdfs_peer *con; @@ -245,7 +246,9 @@ struct cache_file_callback { }; int hmdfs_drop_remote_cache_dents(struct dentry *dentry); +int hmdfs_drop_remote_cache_pages(struct dentry *dentry); void hmdfs_send_drop_push(struct hmdfs_peer *con, const char *path); +void hmdfs_send_drop_page_push(struct hmdfs_peer *con, const char *send_buf, struct inode *inode); void hmdfs_mark_drop_flag(uint64_t device_id, struct dentry *dentry); void hmdfs_clear_drop_flag(struct dentry *dentry); void delete_in_cache_file(uint64_t dev_id, struct dentry *dentry); diff --git a/fs/hmdfs/hmdfs_device_view.h b/fs/hmdfs/hmdfs_device_view.h index a1f792d9eb0f..f235ec8a2429 100644 --- a/fs/hmdfs/hmdfs_device_view.h +++ b/fs/hmdfs/hmdfs_device_view.h @@ -50,7 +50,7 @@ struct hmdfs_dentry_info { struct list_head cache_list_head; spinlock_t cache_list_lock; struct list_head remote_cache_list_head; - struct mutex remote_cache_list_lock; + spinlock_t remote_cache_list_lock; __u8 file_type; __u8 dentry_type; uint64_t device_id; @@ -128,8 +128,11 @@ loff_t hmdfs_file_llseek_local(struct file *file, loff_t offset, int whence); ssize_t hmdfs_do_read_iter(struct file *file, struct iov_iter *iter, loff_t *ppos); -ssize_t hmdfs_do_write_iter(struct file *file, struct iov_iter *iter, - loff_t *ppos); +ssize_t hmdfs_do_write_iter_merge(struct file *file, struct iov_iter *iter, + loff_t *ppos); + +ssize_t hmdfs_do_write_iter_local(struct file *file, struct iov_iter *iter, + loff_t *ppos); int hmdfs_file_release_local(struct inode *inode, struct file *file); int hmdfs_file_mmap_local(struct file *file, struct vm_area_struct *vma); diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index 34b4d579f9d2..16663dcdb7d5 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -21,9 +21,10 @@ #include "server_writeback.h" #include "comm/node_cb.h" -#define HMDFS_MAX_HIDDEN_DIR 1 +#define HMDFS_MAX_HIDDEN_DIR 1 -struct hmdfs_open_info { +struct hmdfs_open_info +{ struct file *file; struct inode *inode; bool stat_valid; @@ -37,7 +38,8 @@ static void find_first_no_slash(const char **name, int *len) const char *s = *name; int l = *len; - while (l > 0 && *s == '/') { + while (l > 0 && *s == '/') + { s++; l--; } @@ -51,7 +53,8 @@ static void find_first_slash(const char **name, int *len) const char *s = *name; int l = *len; - while (l > 0 && *s != '/') { + while (l > 0 && *s != '/') + { s++; l--; } @@ -62,14 +65,15 @@ static void find_first_slash(const char **name, int *len) static bool path_contain_dotdot(const char *name, int len) { - while (true) { + while (true) + { find_first_no_slash(&name, &len); if (len == 0) return false; if (len >= 2 && name[0] == '.' && name[1] == '.' && - (len == 2 || name[2] == '/')) + (len == 2 || name[2] == '/')) return true; find_first_slash(&name, &len); @@ -117,15 +121,18 @@ int remove_file_from_conn(struct hmdfs_peer *conn, __u32 file_id) file = idr_remove(idr, file_id); spin_unlock(lock); - if (!file) { + if (!file) + { return -ENOENT; - } else { + } + else + { return 0; } } struct file *hmdfs_open_link(struct hmdfs_sb_info *sbi, - const char *path) + const char *path) { struct file *file; int err; @@ -134,23 +141,28 @@ struct file *hmdfs_open_link(struct hmdfs_sb_info *sbi, int path_len; path_len = strlen(root_name) + strlen(path) + 2; - if (path_len > PATH_MAX) { + if (path_len > PATH_MAX) + { err = -EINVAL; return ERR_PTR(err); } real_path = kzalloc(path_len, GFP_KERNEL); - if (!real_path) { + if (!real_path) + { err = -ENOMEM; return ERR_PTR(err); } sprintf(real_path, "%s%s", root_name, path); file = filp_open(real_path, O_RDWR | O_LARGEFILE, 0644); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { hmdfs_info("filp_open failed: %ld", PTR_ERR(file)); - } else { - hmdfs_info("get file with magic %lu", - file->f_inode->i_sb->s_magic); + } + else + { + hmdfs_info("get file with magic %lu", + file->f_inode->i_sb->s_magic); } kfree(real_path); @@ -165,21 +177,25 @@ struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) const char *root_name = sbi->local_dst; err = kern_path(root_name, 0, &root_path); - if (err) { + if (err) + { hmdfs_info("kern_path failed: %d", err); return ERR_PTR(err); } file = file_open_root(&root_path, path, - O_RDWR | O_LARGEFILE, 0644); + O_RDWR | O_LARGEFILE, 0644); path_put(&root_path); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { hmdfs_err( "GRAPERR sb->s_readonly_remount %d sb_flag %lu", sbi->sb->s_readonly_remount, sbi->sb->s_flags); hmdfs_info("file_open_root failed: %ld", PTR_ERR(file)); - } else { + } + else + { hmdfs_info("get file with magic %lu", - file->f_inode->i_sb->s_magic); + file->f_inode->i_sb->s_magic); } return file; } @@ -191,7 +207,7 @@ inline void hmdfs_close_path(struct file *file) /* After offline server close all files opened by client */ void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt, - unsigned int seq) + unsigned int seq) { int id; int count = 0; @@ -206,7 +222,8 @@ void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt, /* If there is some open requests in processing, * Maybe, we need to close file when peer offline */ - idr_for_each_entry(idr, filp, id) { + idr_for_each_entry(idr, filp, id) + { hmdfs_debug("[%d]Server close: id=%d", count, id); hmdfs_close_path(filp); count++; @@ -228,11 +245,9 @@ void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt, } static struct hmdfs_node_cb_desc server_cb[] = { - { - .evt = NODE_EVT_OFFLINE, - .sync = true, - .fn = hmdfs_server_offline_notify - }, + {.evt = NODE_EVT_OFFLINE, + .sync = true, + .fn = hmdfs_server_offline_notify}, }; void __init hmdfs_server_add_node_evt_cb(void) @@ -240,8 +255,8 @@ void __init hmdfs_server_add_node_evt_cb(void) hmdfs_node_add_evt_cb(server_cb, ARRAY_SIZE(server_cb)); } -static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, - uint64_t *ino) +static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, + uint64_t *ino) { int ret = 0; struct path root_path; @@ -249,14 +264,16 @@ static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, struct inode *inode = NULL; ret = kern_path(con->sbi->local_dst, 0, &root_path); - if (ret) { + if (ret) + { hmdfs_err("kern_path failed err = %d", ret); return ret; } - ret = vfs_path_lookup(root_path.dentry, root_path.mnt, filename, 0, - &dst_path); - if (ret) { + ret = vfs_path_lookup(root_path.dentry, root_path.mnt, filename, 0, + &dst_path); + if (ret) + { path_put(&root_path); return ret; } @@ -273,14 +290,14 @@ static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, } static const char *datasl_str[] = { - "s0", "s1", "s2", "s3", "s4" -}; + "s0", "s1", "s2", "s3", "s4"}; static int parse_data_sec_level(const char *sl_value, size_t sl_value_len) { int i; - for (i = 0; i < sizeof(datasl_str) / sizeof(datasl_str[0]); i++) { + for (i = 0; i < sizeof(datasl_str) / sizeof(datasl_str[0]); i++) + { if (!strncmp(sl_value, datasl_str[i], strlen(datasl_str[i]))) return i + DATA_SEC_LEVEL0; } @@ -297,34 +314,38 @@ static int check_sec_level(struct hmdfs_peer *node, const char *file_name) char *value = NULL; size_t value_len = DATA_SEC_LEVEL_LENGTH; - if (node->devsl <= 0) { + if (node->devsl <= 0) + { ret = -EACCES; goto out_free; } value = kzalloc(value_len, GFP_KERNEL); - if (!value) { + if (!value) + { ret = -ENOMEM; goto out_free; } err = kern_path(node->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) { + if (err) + { hmdfs_err("get root path error"); ret = err; goto out_free; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, file_name, 0, - &file_path); - if (err) { + &file_path); + if (err) + { hmdfs_err("get file path error"); ret = err; goto out_err; } err = vfs_getxattr(file_path.dentry, DATA_SEC_LEVEL_LABEL, value, - value_len); + value_len); if (err <= 0 && node->devsl >= DATA_SEC_LEVEL3) goto out; if (err > 0 && node->devsl >= parse_data_sec_level(value, err)) @@ -341,26 +362,29 @@ static int check_sec_level(struct hmdfs_peer *node, const char *file_name) } static struct file *hmdfs_open_file(struct hmdfs_peer *con, - const char *filename, uint8_t file_type, - int *file_id) + const char *filename, uint8_t file_type, + int *file_id) { struct file *file = NULL; int err = 0; int id; - if (!filename) { + if (!filename) + { hmdfs_err("filename is NULL"); return ERR_PTR(-EINVAL); } - if (check_sec_level(con, filename)) { + if (check_sec_level(con, filename)) + { hmdfs_err("devsl permission denied"); return ERR_PTR(-EACCES); } - if (hm_isshare(file_type)) { + if (hm_isshare(file_type)) + { err = hmdfs_check_share_access_permission(con->sbi, - filename, con->cid); + filename, con->cid); if (err) return ERR_PTR(err); } @@ -370,14 +394,16 @@ static struct file *hmdfs_open_file(struct hmdfs_peer *con, else file = hmdfs_open_path(con->sbi, filename); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { reset_item_opened_status(con->sbi, filename); return file; } get_file(file); id = insert_file_into_conn(con, file); - if (id < 0) { + if (id < 0) + { hmdfs_err("file_id alloc failed! err=%d", id); reset_item_opened_status(con->sbi, filename); hmdfs_close_path(file); @@ -419,25 +445,26 @@ static struct hmdfs_time_t hmdfs_current_kernel_time(void) * 49 15 (bits) */ static uint64_t hmdfs_server_pack_fid_ver(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd) + struct hmdfs_head_cmd *cmd) { uint64_t boot_cookie = con->sbi->boot_cookie; uint16_t con_cookie = con->fid_cookie; return (boot_cookie | - (con_cookie & ((1 << HMDFS_FID_VER_BOOT_COOKIE_SHIFT) - 1))); + (con_cookie & ((1 << HMDFS_FID_VER_BOOT_COOKIE_SHIFT) - 1))); } static struct file *get_file_by_fid_and_ver(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, - __u32 file_id, __u64 file_ver) + struct hmdfs_head_cmd *cmd, + __u32 file_id, __u64 file_ver) { struct file *file = NULL; __u64 cur_file_ver = hmdfs_server_pack_fid_ver(con, cmd); - if (file_ver != cur_file_ver) { + if (file_ver != cur_file_ver) + { hmdfs_warning("Stale file version %llu for fid %u", - file_ver, file_id); + file_ver, file_id); return ERR_PTR(-EBADF); } @@ -449,18 +476,17 @@ static struct file *get_file_by_fid_and_ver(struct hmdfs_peer *con, } static void hmdfs_update_open_response(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, - struct hmdfs_open_info *info, - struct open_response *resp) + struct hmdfs_head_cmd *cmd, + struct hmdfs_open_info *info, + struct open_response *resp) { struct hmdfs_time_t current_time = hmdfs_current_kernel_time(); - struct hmdfs_time_t ctime = info->stat_valid ? info->stat.ctime : - info->inode->i_ctime; + struct hmdfs_time_t ctime = info->stat_valid ? info->stat.ctime : info->inode->i_ctime; struct hmdfs_time_t precision = msec_to_timespec(con->sbi->dcache_precision); - loff_t size = info->stat_valid ? info->stat.size : - i_size_read(info->inode); + loff_t size = info->stat_valid ? info->stat.size : i_size_read(info->inode); + // NB: info->real_ino is the lower_file's i_ino and i_igeneration, not the info->file's resp->ino = cpu_to_le64(info->real_ino); resp->file_ver = cpu_to_le64(hmdfs_server_pack_fid_ver(con, cmd)); resp->file_id = cpu_to_le32(info->file_id); @@ -477,31 +503,39 @@ static void hmdfs_update_open_response(struct hmdfs_peer *con, * - else, stable_ctime = ctime + dcache_precision; */ precision = hmdfs_time_add(ctime, precision); - if (hmdfs_time_compare(¤t_time, &ctime) < 0) { + if (hmdfs_time_compare(¤t_time, &ctime) < 0) + { resp->stable_ctime = cpu_to_le64(0); resp->stable_ctime_nsec = cpu_to_le32(0); - } else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && - hmdfs_time_compare(¤t_time, &precision) < 0) { + } + else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && + hmdfs_time_compare(¤t_time, &precision) < 0) + { resp->stable_ctime = resp->ctime; resp->stable_ctime_nsec = resp->ctime_nsec; - } else { + } + else + { resp->stable_ctime = cpu_to_le64(precision.tv_sec); resp->stable_ctime_nsec = cpu_to_le32(precision.tv_nsec); } } static int hmdfs_get_open_info(struct hmdfs_peer *con, uint8_t file_type, - const char *filename, - struct hmdfs_open_info *info) + const char *filename, + struct hmdfs_open_info *info) { int ret = 0; info->inode = file_inode(info->file); info->stat_valid = false; - if (con->sbi->sb == info->inode->i_sb) { + if (con->sbi->sb == info->inode->i_sb) + { /* if open a regular file */ info->inode = hmdfs_i(info->inode)->lower_inode; - } else if (con->sbi->lower_sb != info->inode->i_sb) { + } + else if (con->sbi->lower_sb != info->inode->i_sb) + { /* It's possible that inode is not from lower, for example: * 1. touch /f2fs/file * 2. ln -s /sdcard_fs/file /f2fs/link @@ -515,103 +549,50 @@ static int hmdfs_get_open_info(struct hmdfs_peer *con, uint8_t file_type, * information. */ ret = vfs_getattr(&info->file->f_path, &info->stat, STATX_BASIC_STATS | STATX_BTIME, - 0); - if (ret) { + 0); + if (ret) + { hmdfs_err("call vfs_getattr failed, err %d", ret); return ret; } info->stat_valid = true; } - if (hm_islnk(file_type)) { + if (hm_islnk(file_type)) + { ret = hmdfs_get_inode_by_name(con, filename, &info->real_ino); if (ret) return ret; - } else { + } + else + { info->real_ino = generate_u64_ino(info->inode->i_ino, - info->inode->i_generation); + info->inode->i_generation); } return 0; } -void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) -{ - struct open_request *recv = data; - int sizeread = sizeof(struct open_response); - struct open_response *resp = NULL; - struct hmdfs_open_info *info = NULL; - int ret = 0; - - trace_hmdfs_server_open_enter(con, recv); - - resp = kzalloc(sizeread, GFP_KERNEL); - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!resp || !info) { - ret = -ENOMEM; - goto err_free; - } - - if (path_contain_dotdot(recv->buf, recv->path_len)) { - ret = -EINVAL; - goto err_free; - } - - info->file = hmdfs_open_file(con, recv->buf, recv->file_type, - &info->file_id); - if (IS_ERR(info->file)) { - ret = PTR_ERR(info->file); - goto err_free; - } - - ret = hmdfs_get_open_info(con, recv->file_type, recv->buf, info); - if (ret) - goto err_close; - - hmdfs_update_open_response(con, cmd, info, resp); - - trace_hmdfs_server_open_exit(con, resp, info->file, 0); - ret = hmdfs_sendmessage_response(con, cmd, sizeread, resp, 0); - if (ret) { - hmdfs_err("sending msg response failed, file_id %d, err %d", - info->file_id, ret); - remove_file_from_conn(con, info->file_id); - hmdfs_close_path(info->file); - } - hmdfs_close_path(info->file); - kfree(resp); - kfree(info); - return; - -err_close: - hmdfs_close_path(info->file); - remove_file_from_conn(con, info->file_id); - hmdfs_close_path(info->file); -err_free: - kfree(resp); - kfree(info); - trace_hmdfs_server_open_exit(con, NULL, NULL, ret); - hmdfs_send_err_response(con, cmd, ret); -} - static int hmdfs_check_and_create(struct path *path_parent, - struct dentry *dentry, uint64_t device_id, - umode_t mode, bool is_excl) + struct dentry *dentry, uint64_t device_id, + umode_t mode, bool is_excl) { int err = 0; /* if inode doesn't exist, create it */ - if (d_is_negative(dentry)) { + if (d_is_negative(dentry)) + { hmdfs_mark_drop_flag(device_id, path_parent->dentry); err = vfs_create(d_inode(path_parent->dentry), dentry, mode, - is_excl); + is_excl); if (err) hmdfs_err("create failed, err %d", err); - } else { + } + else + { if (is_excl) err = -EEXIST; else if (S_ISREG(d_inode(dentry)->i_mode) && - hm_islnk(hmdfs_d(dentry)->file_type)) + hm_islnk(hmdfs_d(dentry)->file_type)) err = -EINVAL; else if (S_ISDIR(d_inode(dentry)->i_mode)) err = -EISDIR; @@ -620,8 +601,8 @@ static int hmdfs_check_and_create(struct path *path_parent, return err; } static int hmdfs_lookup_create(struct hmdfs_peer *con, - struct atomic_open_request *recv, - struct path *child_path, bool *truncate) + struct atomic_open_request *recv, + struct path *child_path, bool *truncate) { int err = 0; struct path path_root; @@ -632,21 +613,24 @@ static int hmdfs_lookup_create(struct hmdfs_peer *con, struct dentry *dentry = NULL; err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &path_root); - if (err) { + if (err) + { hmdfs_err("no path for %s, err %d", con->sbi->local_dst, err); return err; } err = vfs_path_lookup(path_root.dentry, path_root.mnt, path, - LOOKUP_DIRECTORY, &path_parent); - if (err) { + LOOKUP_DIRECTORY, &path_parent); + if (err) + { hmdfs_info("no dir in %s, err %d", con->sbi->local_dst, err); goto put_path_root; } inode_lock(d_inode(path_parent.dentry)); dentry = lookup_one_len(filename, path_parent.dentry, strlen(filename)); - if (IS_ERR(dentry)) { + if (IS_ERR(dentry)) + { err = PTR_ERR(dentry); inode_unlock(d_inode(path_parent.dentry)); goto put_path_parent; @@ -654,12 +638,15 @@ static int hmdfs_lookup_create(struct hmdfs_peer *con, /* only truncate if inode already exists */ *truncate = ((open_flags & HMDFS_O_TRUNC) && d_is_positive(dentry)); err = hmdfs_check_and_create(&path_parent, dentry, con->device_id, - le16_to_cpu(recv->mode), - open_flags & HMDFS_O_EXCL); + le16_to_cpu(recv->mode), + open_flags & HMDFS_O_EXCL); inode_unlock(d_inode(path_parent.dentry)); - if (err) { + if (err) + { dput(dentry); - } else { + } + else + { child_path->dentry = dentry; child_path->mnt = mntget(path_parent.mnt); } @@ -672,13 +659,14 @@ static int hmdfs_lookup_create(struct hmdfs_peer *con, } static int hmdfs_dentry_open(struct hmdfs_peer *con, - const struct path *path, - struct hmdfs_open_info *info) + const struct path *path, + struct hmdfs_open_info *info) { int err = 0; info->file = dentry_open(path, O_RDWR | O_LARGEFILE, current_cred()); - if (IS_ERR(info->file)) { + if (IS_ERR(info->file)) + { err = PTR_ERR(info->file); hmdfs_err("open file failed, err %d", err); return err; @@ -686,7 +674,8 @@ static int hmdfs_dentry_open(struct hmdfs_peer *con, get_file(info->file); info->file_id = insert_file_into_conn(con, info->file); - if (info->file_id < 0) { + if (info->file_id < 0) + { err = info->file_id; hmdfs_err("file_id alloc failed! err %d", err); hmdfs_close_path(info->file); @@ -698,10 +687,10 @@ static int hmdfs_dentry_open(struct hmdfs_peer *con, } static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, - struct atomic_open_request *recv, - struct hmdfs_open_info *info, - struct atomic_open_response *resp) + struct hmdfs_head_cmd *cmd, + struct atomic_open_request *recv, + struct hmdfs_open_info *info, + struct atomic_open_response *resp) { struct path child_path; bool truncate = false; @@ -719,9 +708,11 @@ static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, if (err) goto fail_close; - if (truncate) { + if (truncate) + { err = vfs_truncate(&child_path, 0); - if (err) { + if (err) + { hmdfs_err("truncate failed, err %d", err); goto fail_close; } @@ -730,7 +721,8 @@ static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, resp->i_mode = cpu_to_le16(file_inode(info->file)->i_mode); fail_close: - if (err) { + if (err) + { remove_file_from_conn(con, info->file_id); hmdfs_close_path(info->file); hmdfs_close_path(info->file); @@ -741,7 +733,7 @@ static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, } void hmdfs_server_atomic_open(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { int err; struct atomic_open_request *recv = data; @@ -750,18 +742,21 @@ void hmdfs_server_atomic_open(struct hmdfs_peer *con, char *file_path = recv->buf; char *file = recv->buf + recv->path_len + 1; - if (path_contain_dotdot(file_path, recv->path_len)) { + if (path_contain_dotdot(file_path, recv->path_len)) + { err = -EINVAL; goto out; } - if (path_contain_dotdot(file, recv->file_len)) { + if (path_contain_dotdot(file, recv->file_len)) + { err = -EINVAL; goto out; } info = kmalloc(sizeof(*info), GFP_KERNEL); resp = kzalloc(sizeof(*resp), GFP_KERNEL); - if (!resp || !info) { + if (!resp || !info) + { err = -ENOMEM; goto out; } @@ -769,14 +764,18 @@ void hmdfs_server_atomic_open(struct hmdfs_peer *con, err = hmdfs_server_do_atomic_open(con, cmd, recv, info, resp); out: - if (err) { + if (err) + { hmdfs_send_err_response(con, cmd, err); - } else { + } + else + { err = hmdfs_sendmessage_response(con, cmd, sizeof(*resp), resp, - 0); - if (err) { + 0); + if (err) + { hmdfs_err("sending msg response failed, file_id %d, err %d", - info->file_id, err); + info->file_id, err); remove_file_from_conn(con, info->file_id); hmdfs_close_path(info->file); } @@ -786,7 +785,7 @@ void hmdfs_server_atomic_open(struct hmdfs_peer *con, } void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct release_request *release_recv = data; struct file *file = NULL; @@ -797,7 +796,8 @@ void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, file_id = le32_to_cpu(release_recv->file_id); file_ver = le64_to_cpu(release_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { hmdfs_err("cannot find %u", file_id); ret = PTR_ERR(file); goto out; @@ -810,7 +810,8 @@ void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_close_path(file); hmdfs_info("close %u", file_id); ret = remove_file_from_conn(con, file_id); - if (ret) { + if (ret) + { hmdfs_err("cannot find after close %u", file_id); goto out; } @@ -823,7 +824,7 @@ void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct fsync_request *fsync_recv = data; __s32 datasync = le32_to_cpu(fsync_recv->datasync); @@ -837,7 +838,8 @@ void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, file_id = le32_to_cpu(fsync_recv->file_id); file_ver = le64_to_cpu(fsync_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { hmdfs_err("cannot find %u", file_id); ret = PTR_ERR(file); goto out; @@ -853,7 +855,7 @@ void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct readpage_request *readpage_recv = data; __u64 file_ver; @@ -867,7 +869,8 @@ void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, file_id = le32_to_cpu(readpage_recv->file_id); file_ver = le64_to_cpu(readpage_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { hmdfs_info( "file with id %u does not exist, pgindex %llu, devid %llu", file_id, le64_to_cpu(readpage_recv->index), @@ -881,16 +884,20 @@ void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, goto fail_put_file; readpage = kmalloc(read_len, GFP_KERNEL); - if (!readpage) { + if (!readpage) + { ret = -ENOMEM; goto fail_put_file; } pos = (loff_t)le64_to_cpu(readpage_recv->index) << HMDFS_PAGE_OFFSET; ret = kernel_read(file, readpage->buf, read_len, &pos); - if (ret < 0) { + if (ret < 0) + { hmdfs_send_err_response(con, cmd, -EIO); - } else { + } + else + { if (ret != read_len) memset(readpage->buf + ret, 0, read_len - ret); hmdfs_sendmessage_response(con, cmd, read_len, readpage, 0); @@ -907,18 +914,18 @@ void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } static bool need_rebuild_dcache(struct hmdfs_dcache_header *h, - struct hmdfs_time_t time, - unsigned int precision) -{ - struct hmdfs_time_t crtime = { .tv_sec = le64_to_cpu(h->dcache_crtime), - .tv_nsec = le64_to_cpu( - h->dcache_crtime_nsec) }; - struct hmdfs_time_t ctime = { .tv_sec = le64_to_cpu(h->dentry_ctime), - .tv_nsec = le64_to_cpu( - h->dentry_ctime_nsec) }; - struct hmdfs_time_t pre_time = { .tv_sec = precision / MSEC_PER_SEC, - .tv_nsec = precision % MSEC_PER_SEC * - NSEC_PER_MSEC }; + struct hmdfs_time_t time, + unsigned int precision) +{ + struct hmdfs_time_t crtime = {.tv_sec = le64_to_cpu(h->dcache_crtime), + .tv_nsec = le64_to_cpu( + h->dcache_crtime_nsec)}; + struct hmdfs_time_t ctime = {.tv_sec = le64_to_cpu(h->dentry_ctime), + .tv_nsec = le64_to_cpu( + h->dentry_ctime_nsec)}; + struct hmdfs_time_t pre_time = {.tv_sec = precision / MSEC_PER_SEC, + .tv_nsec = precision % MSEC_PER_SEC * + NSEC_PER_MSEC}; if (hmdfs_time_compare(&time, &ctime) != 0) return true; @@ -931,7 +938,7 @@ static bool need_rebuild_dcache(struct hmdfs_dcache_header *h, } static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode, - unsigned long precision) + unsigned long precision) { struct hmdfs_dcache_header header; int overallpage; @@ -939,13 +946,15 @@ static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode, loff_t pos = 0; overallpage = get_dentry_group_cnt(file_inode(filp)); - if (overallpage == 0) { + if (overallpage == 0) + { hmdfs_err("cache file size is 0"); return false; } bytes = kernel_read(filp, &header, sizeof(header), &pos); - if (bytes != sizeof(header)) { + if (bytes != sizeof(header)) + { hmdfs_err("read file failed, err:%zd", bytes); return false; } @@ -954,8 +963,8 @@ static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode, } struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi, - const char *recvpath, - struct path *path) + const char *recvpath, + struct path *path) { struct cache_file_node *cfn = NULL; struct file *file; @@ -965,7 +974,8 @@ struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi, return NULL; if (!hmdfs_server_cache_validate(cfn->filp, path->dentry->d_inode, - sbi->dcache_precision)) { + sbi->dcache_precision)) + { remove_cfn(cfn); release_cfn(cfn); return NULL; @@ -978,8 +988,8 @@ struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi, } bool hmdfs_client_cache_validate(struct hmdfs_sb_info *sbi, - struct readdir_request *readdir_recv, - struct path *path) + struct readdir_request *readdir_recv, + struct path *path) { struct inode *inode = path->dentry->d_inode; struct hmdfs_dcache_header header; @@ -994,11 +1004,11 @@ bool hmdfs_client_cache_validate(struct hmdfs_sb_info *sbi, header.dentry_ctime_nsec = readdir_recv->dentry_ctime_nsec; return !need_rebuild_dcache(&header, inode->i_ctime, - sbi->dcache_precision); + sbi->dcache_precision); } static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, - struct dentry *lo_d) + struct dentry *lo_d) { struct hmdfs_dentry_info *di = hmdfs_d(peer->sbi->sb->s_root); struct dentry *lo_d_root = di->lower_path.dentry; @@ -1014,12 +1024,14 @@ static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, /* To generate a reversed path str */ for (lo_d_tmp = lo_d; lo_d_tmp != lo_d_root && !IS_ROOT(lo_d_tmp); - lo_d_tmp = lo_d_tmp->d_parent) { + lo_d_tmp = lo_d_tmp->d_parent) + { u32 dlen = lo_d_tmp->d_name.len; int reverse_index = dlen - 1; /* Considering the appended slash and '\0' */ - if (unlikely(path_len + dlen + 1 > PATH_MAX - 1)) { + if (unlikely(path_len + dlen + 1 > PATH_MAX - 1)) + { kfree(lo_p_buf); return ERR_PTR(-ENAMETOOLONG); } @@ -1031,7 +1043,7 @@ static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, /* Reverse the reversed path str to get the real path str */ for (buf_head = lo_p_buf, buf_tail = lo_p_buf + path_len - 1; - buf_head < buf_tail; ++buf_head, --buf_tail) + buf_head < buf_tail; ++buf_head, --buf_tail) swap(*buf_head, *buf_tail); if (path_len == 0) @@ -1040,7 +1052,7 @@ static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, } static int server_lookup(struct hmdfs_peer *peer, const char *req_path, - struct path *path) + struct path *path) { struct path root_path; int err = 0; @@ -1050,7 +1062,7 @@ static int server_lookup(struct hmdfs_peer *peer, const char *req_path, goto out_noroot; err = vfs_path_lookup(root_path.dentry, root_path.mnt, req_path, - LOOKUP_DIRECTORY, path); + 0, path); path_put(&root_path); out_noroot: return err; @@ -1065,7 +1077,7 @@ static int server_lookup(struct hmdfs_peer *peer, const char *req_path, * return the lower path's name, with characters' cases matched */ static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path, - struct path *lo_p) + struct path *lo_p) { char *lo_p_name = ERR_PTR(-ENOENT); struct path up_p; @@ -1079,7 +1091,8 @@ static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path, path_put(&up_p); lo_p_name = server_lower_dentry_path_raw(peer, lo_p->dentry); - if (IS_ERR(lo_p_name)) { + if (IS_ERR(lo_p_name)) + { err = PTR_ERR(lo_p_name); path_put(lo_p); } @@ -1087,8 +1100,92 @@ static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path, return err ? ERR_PTR(err) : lo_p_name; } +void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, + void *data) +{ + struct open_request *recv = data; + int sizeread = sizeof(struct open_response); + struct open_response *resp = NULL; + struct hmdfs_open_info *info = NULL; + int ret = 0; + loff_t pos = 0; + + struct path lo_p; + char *lo_p_name = NULL; + + trace_hmdfs_server_open_enter(con, recv); + + resp = kzalloc(sizeread, GFP_KERNEL); + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!resp || !info) + { + ret = -ENOMEM; + goto err_free; + } + + if (path_contain_dotdot(recv->buf, recv->path_len)) + { + ret = -EINVAL; + goto err_free; + } + + info->file = hmdfs_open_file(con, recv->buf, recv->file_type, + &info->file_id); + + if (IS_ERR(info->file)) + { + ret = PTR_ERR(info->file); + goto err_free; + } + + ret = hmdfs_get_open_info(con, recv->file_type, recv->buf, info); + if (ret) + goto err_close; + + hmdfs_update_open_response(con, cmd, info, resp); + + ret = kernel_read(info->file, resp->page, HMDFS_PAGE_SIZE, &pos); + if (ret < 0) + { + resp->read_success = 0; + } + else + { + resp->read_success = 1; + if (ret != HMDFS_PAGE_SIZE) + memset(resp->page + ret, 0, HMDFS_PAGE_SIZE - ret); + } + + trace_hmdfs_server_open_exit(con, resp, info->file, 0); + ret = hmdfs_sendmessage_response(con, cmd, sizeread, resp, 0); + if (ret) + { + hmdfs_err("sending msg response failed, file_id %d, err %d", + info->file_id, ret); + remove_file_from_conn(con, info->file_id); + goto out; + } + hmdfs_add_remote_page_cache_list(con, info->file); + +out: + hmdfs_close_path(info->file); + kfree(resp); + kfree(info); + return; + +err_close: + hmdfs_close_path(info->file); + remove_file_from_conn(con, info->file_id); + hmdfs_close_path(info->file); +err_free: + kfree(resp); + kfree(info); + trace_hmdfs_server_open_exit(con, NULL, NULL, ret); + hmdfs_send_err_response(con, cmd, ret); +} + void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct readdir_request *readdir_recv = data; struct path lo_p; @@ -1099,28 +1196,33 @@ void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, trace_hmdfs_server_readdir(readdir_recv); - if (path_contain_dotdot(readdir_recv->path, readdir_recv->path_len)) { + if (path_contain_dotdot(readdir_recv->path, readdir_recv->path_len)) + { err = -EINVAL; goto send_err; } lo_p_name = server_lookup_lower(con, readdir_recv->path, &lo_p); - if (IS_ERR(lo_p_name)) { + if (IS_ERR(lo_p_name)) + { err = PTR_ERR(lo_p_name); hmdfs_info("Failed to get lower path: %d", err); goto send_err; } - if (le32_to_cpu(readdir_recv->verify_cache)) { + if (le32_to_cpu(readdir_recv->verify_cache)) + { if (hmdfs_client_cache_validate(con->sbi, readdir_recv, &lo_p)) goto out_response; } filp = hmdfs_server_cache_revalidate(con->sbi, lo_p_name, &lo_p); - if (IS_ERR_OR_NULL(filp)) { + if (IS_ERR_OR_NULL(filp)) + { filp = hmdfs_server_rebuild_dents(con->sbi, &lo_p, &num, - lo_p_name); - if (IS_ERR_OR_NULL(filp)) { + lo_p_name); + if (IS_ERR_OR_NULL(filp)) + { err = PTR_ERR(filp); goto err_lookup_path; } @@ -1143,7 +1245,7 @@ void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct mkdir_request *mkdir_recv = data; @@ -1156,26 +1258,30 @@ void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, int path_len = le32_to_cpu(mkdir_recv->path_len); mkdir_resp = kzalloc(respsize, GFP_KERNEL); - if (!mkdir_resp) { + if (!mkdir_resp) + { err = -ENOMEM; goto mkdir_out; } mkdir_dir = mkdir_recv->path; mkdir_name = mkdir_recv->path + path_len + 1; - if (path_contain_dotdot(mkdir_dir, mkdir_recv->path_len)) { + if (path_contain_dotdot(mkdir_dir, mkdir_recv->path_len)) + { err = -EINVAL; goto mkdir_out; } - if (path_contain_dotdot(mkdir_name, mkdir_recv->name_len)) { + if (path_contain_dotdot(mkdir_name, mkdir_recv->name_len)) + { err = -EINVAL; goto mkdir_out; } dent = hmdfs_root_mkdir(con->device_id, con->sbi->local_dst, - mkdir_dir, mkdir_name, - le16_to_cpu(mkdir_recv->mode)); - if (IS_ERR(dent)) { + mkdir_dir, mkdir_name, + le16_to_cpu(mkdir_recv->mode)); + if (IS_ERR(dent)) + { err = PTR_ERR(dent); hmdfs_err("hmdfs_root_mkdir failed err = %d", err); goto mkdir_out; @@ -1193,7 +1299,7 @@ void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct create_request *create_recv = data; @@ -1206,27 +1312,31 @@ void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, int path_len = le32_to_cpu(create_recv->path_len); create_resp = kzalloc(respsize, GFP_KERNEL); - if (!create_resp) { + if (!create_resp) + { err = -ENOMEM; goto create_out; } create_dir = create_recv->path; create_name = create_recv->path + path_len + 1; - if (path_contain_dotdot(create_dir, create_recv->path_len)) { + if (path_contain_dotdot(create_dir, create_recv->path_len)) + { err = -EINVAL; goto create_out; } - if (path_contain_dotdot(create_name, create_recv->name_len)) { + if (path_contain_dotdot(create_name, create_recv->name_len)) + { err = -EINVAL; goto create_out; } dent = hmdfs_root_create(con->device_id, con->sbi->local_dst, - create_dir, create_name, - le16_to_cpu(create_recv->mode), - create_recv->want_excl); - if (IS_ERR(dent)) { + create_dir, create_name, + le16_to_cpu(create_recv->mode), + create_recv->want_excl); + if (IS_ERR(dent)) + { err = PTR_ERR(dent); hmdfs_err("hmdfs_root_create failed err = %d", err); goto create_out; @@ -1242,7 +1352,7 @@ void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, */ create_resp->i_ino = cpu_to_le64( generate_u64_ino(hmdfs_i(child_inode)->lower_inode->i_ino, - child_inode->i_generation)); + child_inode->i_generation)); dput(dent); create_out: hmdfs_sendmessage_response(con, cmd, respsize, create_resp, err); @@ -1250,7 +1360,7 @@ void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct path root_path; @@ -1260,17 +1370,20 @@ void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, path = rmdir_recv->path; name = rmdir_recv->path + le32_to_cpu(rmdir_recv->path_len) + 1; - if (path_contain_dotdot(path, rmdir_recv->path_len)) { + if (path_contain_dotdot(path, rmdir_recv->path_len)) + { err = -EINVAL; goto rmdir_out; } - if (path_contain_dotdot(name, rmdir_recv->name_len)) { + if (path_contain_dotdot(name, rmdir_recv->name_len)) + { err = -EINVAL; goto rmdir_out; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (!err) { + if (!err) + { err = hmdfs_root_rmdir(con->device_id, &root_path, path, name); path_put(&root_path); } @@ -1280,7 +1393,7 @@ void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct path root_path; @@ -1290,17 +1403,20 @@ void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, path = unlink_recv->path; name = unlink_recv->path + le32_to_cpu(unlink_recv->path_len) + 1; - if (path_contain_dotdot(path, unlink_recv->path_len)) { + if (path_contain_dotdot(path, unlink_recv->path_len)) + { err = -EINVAL; goto unlink_out; } - if (path_contain_dotdot(name, unlink_recv->name_len)) { + if (path_contain_dotdot(name, unlink_recv->name_len)) + { err = -EINVAL; goto unlink_out; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (!err) { + if (!err) + { err = hmdfs_root_unlink(con->device_id, &root_path, path, name); path_put(&root_path); } @@ -1310,7 +1426,7 @@ void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_rename(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; int old_path_len; @@ -1334,33 +1450,37 @@ void hmdfs_server_rename(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, path_new = recv->path + old_path_len + 1; name_old = recv->path + old_path_len + 1 + new_path_len + 1; name_new = recv->path + old_path_len + 1 + new_path_len + 1 + - old_name_len + 1; - if (path_contain_dotdot(path_old, old_path_len)) { + old_name_len + 1; + if (path_contain_dotdot(path_old, old_path_len)) + { err = -EINVAL; goto rename_out; } - if (path_contain_dotdot(path_new, new_path_len)) { + if (path_contain_dotdot(path_new, new_path_len)) + { err = -EINVAL; goto rename_out; } - if (path_contain_dotdot(name_old, old_name_len)) { + if (path_contain_dotdot(name_old, old_name_len)) + { err = -EINVAL; goto rename_out; } - if (path_contain_dotdot(name_new, new_name_len)) { + if (path_contain_dotdot(name_new, new_name_len)) + { err = -EINVAL; goto rename_out; } err = hmdfs_root_rename(con->sbi, con->device_id, path_old, name_old, - path_new, name_new, flags); + path_new, name_new, flags); rename_out: hmdfs_send_err_response(con, cmd, err); } -static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, - ... ) +static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, + ...) { int ret; va_list args; @@ -1368,23 +1488,26 @@ static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, if (!path) return -ENOMEM; - + va_start(args, path_fmt); ret = vsnprintf(path, PATH_MAX, path_fmt, args); va_end(args); - if(ret >= PATH_MAX) { + if (ret >= PATH_MAX) + { ret = -ENAMETOOLONG; goto out; } ret = kern_path(path, LOOKUP_FOLLOW, link_path); - if (ret) { + if (ret) + { hmdfs_err("kern_path failed err = %d", ret); goto out; } - if (!S_ISREG(d_inode(link_path->dentry)->i_mode)) { + if (!S_ISREG(d_inode(link_path->dentry)->i_mode)) + { hmdfs_err("path is dir symlink"); path_put(link_path); ret = -EOPNOTSUPP; @@ -1396,7 +1519,8 @@ static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, return ret; } -struct dir_entry_info { +struct dir_entry_info +{ struct list_head list; char *name; int name_len; @@ -1404,15 +1528,16 @@ struct dir_entry_info { }; static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, - int name_len, loff_t offset, u64 ino, - unsigned int d_type) + int name_len, loff_t offset, u64 ino, + unsigned int d_type) { int res = 0; char namestr[NAME_MAX + 1]; struct getdents_callback_real *gc = NULL; struct dentry *child = NULL; - if (name_len > NAME_MAX) { + if (name_len > NAME_MAX) + { hmdfs_err("name_len:%d NAME_MAX:%u", name_len, NAME_MAX); goto out; } @@ -1427,34 +1552,43 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, /* parent lock already hold by iterate_dir */ child = lookup_one_len(name, gc->parent_path->dentry, name_len); - if (IS_ERR(child)) { + if (IS_ERR(child)) + { res = PTR_ERR(child); hmdfs_err("lookup failed because %d", res); goto out; } - if (d_really_is_negative(child)) { + if (d_really_is_negative(child)) + { dput(child); hmdfs_err("lookup failed because negative dentry"); /* just do not fill this entry and continue for next entry */ goto out; } - if (d_type == DT_REG || d_type == DT_DIR) { + if (d_type == DT_REG || d_type == DT_DIR) + { + // gc->file is dentry_file, the anonymous tmp_file create_dentry(child, d_inode(child), gc->file, gc->sbi); gc->num++; - } else if (d_type == DT_LNK) { + } + else if (d_type == DT_LNK) + { struct path link_path; - res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", - gc->sbi->local_src, gc->dir, - name); - if (!res) { - create_dentry(child, d_inode(link_path.dentry), - gc->file, gc->sbi); + res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", + gc->sbi->local_src, gc->dir, + name); + if (!res) + { + create_dentry(child, d_inode(link_path.dentry), + gc->file, gc->sbi); path_put(&link_path); gc->num++; - } else if (res == -ENOENT) { + } + else if (res == -ENOENT) + { create_dentry(child, d_inode(child), gc->file, gc->sbi); gc->num++; } @@ -1470,7 +1604,7 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, } static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, - struct file *file, struct file *dentry_file) + struct file *file, struct file *dentry_file) { struct inode *inode = NULL; struct hmdfs_time_t cur_time; @@ -1485,8 +1619,8 @@ static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, // Get the dentries of target directory struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, - struct path *path, loff_t *num, - const char *dir) + struct path *path, loff_t *num, + const char *dir) { int err = 0; struct getdents_callback_real gc = { @@ -1500,14 +1634,18 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, struct file *dentry_file = NULL; struct hmdfs_dcache_header header; + // create a anonymous tmp_file in sbi->cache_dir dentry_file = create_local_dentry_file_cache(sbi); - if (IS_ERR(dentry_file)) { + if (IS_ERR(dentry_file)) + { hmdfs_err("file create failed err=%ld", PTR_ERR(dentry_file)); return dentry_file; } + // path is the lower path of the target dir file = dentry_open(path, O_RDONLY | O_DIRECTORY, current_cred()); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { err = PTR_ERR(file); hmdfs_err("dentry_open failed"); goto out; @@ -1519,7 +1657,8 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, gc.file = dentry_file; err = iterate_dir(file, &(gc.ctx)); - if (err) { + if (err) + { hmdfs_err("iterate_dir failed"); goto out; } @@ -1534,7 +1673,8 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, if (!IS_ERR_OR_NULL(file)) fput(file); - if (err) { + if (err) + { fput(dentry_file); dentry_file = ERR_PTR(err); } @@ -1544,7 +1684,7 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, } void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct writepage_request *writepage_recv = data; struct hmdfs_server_writeback *hswb = NULL; @@ -1556,10 +1696,15 @@ void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, ssize_t ret; int err = 0; + struct remotecache_item *item = NULL; + struct remotecache_item *item_temp = NULL; + struct hmdfs_dentry_info *d_info = NULL; + file_id = le32_to_cpu(writepage_recv->file_id); file_ver = le64_to_cpu(writepage_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) { + if (IS_ERR(file)) + { hmdfs_info( "file with id %u does not exist, pgindex %llu, devid %llu", file_id, le64_to_cpu(writepage_recv->index), @@ -1567,12 +1712,27 @@ void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, err = PTR_ERR(file); goto out; } + d_info = hmdfs_d(file->f_path.dentry); pos = (loff_t)le64_to_cpu(writepage_recv->index) << HMDFS_PAGE_OFFSET; count = le32_to_cpu(writepage_recv->count); ret = kernel_write(file, writepage_recv->buf, count, &pos); if (ret != count) err = -EIO; + else if (d_info) + { + spin_lock(&d_info->remote_cache_list_lock); + list_for_each_entry_safe(item, item_temp, + &(d_info->remote_cache_list_head), list) + { + if (item->con->device_id == con->device_id) + { + item->drop_flag = 1; + break; + } + } + spin_unlock(&d_info->remote_cache_list_lock); + } hmdfs_close_path(file); out: @@ -1583,21 +1743,24 @@ void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_server_check_writeback(hswb); } -static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, - const char *path_name, struct path *dst_path) +static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, + const char *path_name, struct path *dst_path) { struct path link_path; int err; - err = hmdfs_lookup_symlink(&link_path, "%s/%s", sbi->local_dst, - path_name); + err = hmdfs_lookup_symlink(&link_path, "%s/%s", sbi->local_dst, + path_name); if (err) return err; - - if (d_inode(link_path.dentry)->i_sb != sbi->sb) { + + if (d_inode(link_path.dentry)->i_sb != sbi->sb) + { path_put(dst_path); *dst_path = link_path; - } else { + } + else + { path_put(&link_path); } @@ -1605,13 +1768,14 @@ static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, } static struct inode *hmdfs_verify_path(struct dentry *dentry, char *recv_buf, - struct super_block *sb) + struct super_block *sb) { struct inode *inode = d_inode(dentry); struct hmdfs_inode_info *info = NULL; /* if we found path from wrong fs */ - if (inode->i_sb != sb) { + if (inode->i_sb != sb) + { hmdfs_err("super block do not match"); return NULL; } @@ -1626,13 +1790,13 @@ static struct inode *hmdfs_verify_path(struct dentry *dentry, char *recv_buf, * possible because dentry cache can contain stale data. */ hmdfs_info("lower inode is NULL, is remote file: %d", - info->conn != NULL); + info->conn != NULL); return NULL; } static int hmdfs_notify_change(struct vfsmount *mnt, struct dentry *dentry, - struct iattr *attr, - struct inode **delegated_inode) + struct iattr *attr, + struct inode **delegated_inode) { #ifdef CONFIG_SDCARD_FS /* sdcard_fs need to call setattr2, notify_change will call setattr */ @@ -1643,7 +1807,7 @@ static int hmdfs_notify_change(struct vfsmount *mnt, struct dentry *dentry, } void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct dentry *dentry = NULL; @@ -1653,31 +1817,35 @@ void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, struct iattr attr; __u32 valid = le32_to_cpu(recv->valid); - if (path_contain_dotdot(recv->buf, recv->path_len)) { + if (path_contain_dotdot(recv->buf, recv->path_len)) + { err = -EINVAL; goto out; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (err) { + if (err) + { hmdfs_err("kern_path failed err = %d", err); goto out; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf, 0, - &dst_path); + &dst_path); if (err) goto out_put_root; inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb); - if (!inode) { + if (!inode) + { err = -ENOENT; goto out_put_dst; } - if (S_ISLNK(inode->i_mode)) { + if (S_ISLNK(inode->i_mode)) + { err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); - if(err == -ENOENT) + if (err == -ENOENT) err = 0; else if (err) goto out_put_dst; @@ -1706,8 +1874,8 @@ void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } static void update_getattr_response(struct hmdfs_peer *con, struct inode *inode, - struct kstat *ks, - struct getattr_response *resp) + struct kstat *ks, + struct getattr_response *resp) { /* if getattr for link, get ino and mode from actual lower inode */ resp->ino = cpu_to_le64( @@ -1734,7 +1902,7 @@ static void update_getattr_response(struct hmdfs_peer *con, struct inode *inode, } void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct getattr_request *recv = data; @@ -1746,7 +1914,8 @@ void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, unsigned int recv_flags = le32_to_cpu(recv->lookup_flags); unsigned int lookup_flags = 0; - if (path_contain_dotdot(recv->buf, recv->path_len)) { + if (path_contain_dotdot(recv->buf, recv->path_len)) + { err = -EINVAL; goto err; } @@ -1756,30 +1925,34 @@ void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, goto err; resp = kzalloc(size_read, GFP_KERNEL); - if (!resp) { + if (!resp) + { err = -ENOMEM; goto err; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (err) { + if (err) + { hmdfs_err("kern_path failed err = %d", err); goto err_free_resp; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf, - lookup_flags, &dst_path); + lookup_flags, &dst_path); if (err) goto out_put_root; inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb); - if (!inode) { + if (!inode) + { err = -ENOENT; goto out_put_dst; } - if (S_ISLNK(inode->i_mode)) { + if (S_ISLNK(inode->i_mode)) + { err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); - if(err && err != -ENOENT) + if (err && err != -ENOENT) goto out_put_dst; } @@ -1812,7 +1985,7 @@ void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } static void init_statfs_response(struct statfs_response *resp, - struct kstatfs *st) + struct kstatfs *st) { resp->f_type = cpu_to_le64(HMDFS_SUPER_MAGIC); resp->f_bsize = cpu_to_le64(st->f_bsize); @@ -1834,7 +2007,7 @@ static void init_statfs_response(struct statfs_response *resp, } void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct statfs_request *recv = data; struct statfs_response *resp = NULL; @@ -1842,32 +2015,37 @@ void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, struct kstatfs *st = NULL; int err = 0; - if (path_contain_dotdot(recv->path, recv->path_len)) { + if (path_contain_dotdot(recv->path, recv->path_len)) + { err = -EINVAL; goto out; } st = kzalloc(sizeof(*st), GFP_KERNEL); - if (!st) { + if (!st) + { err = -ENOMEM; goto out; } resp = kmalloc(sizeof(*resp), GFP_KERNEL); - if (!resp) { + if (!resp) + { err = -ENOMEM; goto free_st; } err = kern_path(con->sbi->local_src, 0, &root_path); - if (err) { + if (err) + { hmdfs_info("kern_path failed err = %d", err); goto free_st; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->path, 0, - &path); - if (err) { + &path); + if (err) + { hmdfs_info("recv->path found failed err = %d", err); goto put_root; } @@ -1892,7 +2070,7 @@ void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_syncfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { /* * Reserved interface. There is a difference compared with traditional @@ -1907,7 +2085,7 @@ void hmdfs_server_syncfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_getxattr(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct getxattr_request *recv = data; size_t size = le32_to_cpu(recv->size); @@ -1919,30 +2097,35 @@ void hmdfs_server_getxattr(struct hmdfs_peer *con, char *name = recv->buf + recv->path_len + 1; int err = -ENOMEM; - if (path_contain_dotdot(file_path, recv->path_len)) { + if (path_contain_dotdot(file_path, recv->path_len)) + { err = -EINVAL; goto err; } - if (path_contain_dotdot(name, recv->name_len)) { + if (path_contain_dotdot(name, recv->name_len)) + { err = -EINVAL; goto err; } resp = kzalloc(size_read, GFP_KERNEL); - if (!resp) { + if (!resp) + { err = -ENOMEM; goto err; } err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) { + if (err) + { hmdfs_info("kern_path failed err = %d", err); goto err_free_resp; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, - file_path, 0, &path); - if (err) { + file_path, 0, &path); + if (err) + { hmdfs_info("path found failed err = %d", err); goto err_put_root; } @@ -1951,7 +2134,8 @@ void hmdfs_server_getxattr(struct hmdfs_peer *con, err = vfs_getxattr(path.dentry, name, NULL, size); else err = vfs_getxattr(path.dentry, name, resp->value, size); - if (err < 0) { + if (err < 0) + { hmdfs_info("getxattr failed err %d", err); goto err_put_path; } @@ -1974,7 +2158,7 @@ void hmdfs_server_getxattr(struct hmdfs_peer *con, } void hmdfs_server_setxattr(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct setxattr_request *recv = data; size_t size = le32_to_cpu(recv->size); @@ -1987,31 +2171,38 @@ void hmdfs_server_setxattr(struct hmdfs_peer *con, const void *value = name + recv->name_len + 1; int err; - if (path_contain_dotdot(file_path, recv->path_len)) { + if (path_contain_dotdot(file_path, recv->path_len)) + { err = -EINVAL; goto err; } - if (path_contain_dotdot(name, recv->name_len)) { + if (path_contain_dotdot(name, recv->name_len)) + { err = -EINVAL; goto err; } err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) { + if (err) + { hmdfs_info("kern_path failed err = %d", err); goto err; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, - file_path, 0, &path); - if (err) { + file_path, 0, &path); + if (err) + { hmdfs_info("path found failed err = %d", err); goto err_put_root; } - if (del) { + if (del) + { WARN_ON(flags != XATTR_REPLACE); err = vfs_removexattr(path.dentry, name); - } else { + } + else + { err = vfs_setxattr(path.dentry, name, value, size, flags); } @@ -2023,7 +2214,7 @@ void hmdfs_server_setxattr(struct hmdfs_peer *con, } void hmdfs_server_listxattr(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct listxattr_request *recv = data; size_t size = le32_to_cpu(recv->size); @@ -2034,25 +2225,29 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, struct path path; int err = 0; - if (path_contain_dotdot(file_path, recv->path_len)) { + if (path_contain_dotdot(file_path, recv->path_len)) + { err = -EINVAL; goto err; } resp = kzalloc(size_read, GFP_KERNEL); - if (!resp) { + if (!resp) + { err = -ENOMEM; goto err; } err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) { + if (err) + { hmdfs_info("kern_path failed err = %d", err); goto err_free_resp; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, - file_path, 0, &path); - if (err) { + file_path, 0, &path); + if (err) + { hmdfs_info("path found failed err = %d", err); goto err_put_root; } @@ -2061,7 +2256,8 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, err = vfs_listxattr(path.dentry, NULL, size); else err = vfs_listxattr(path.dentry, resp->list, size); - if (err < 0) { + if (err < 0) + { hmdfs_info("listxattr failed err = %d", err); goto err_put_path; } @@ -2084,20 +2280,22 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, } void hmdfs_server_get_drop_push(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct drop_push_request *dp_recv = data; struct path root_path, path; int err; char *tmp_path = NULL; - if (path_contain_dotdot(dp_recv->path, dp_recv->path_len)) { + if (path_contain_dotdot(dp_recv->path, dp_recv->path_len)) + { err = -EINVAL; goto quickack; } err = kern_path(con->sbi->real_dst, 0, &root_path); - if (err) { + if (err) + { hmdfs_err("kern_path failed err = %d", err); goto quickack; } @@ -2105,11 +2303,12 @@ void hmdfs_server_get_drop_push(struct hmdfs_peer *con, if (!tmp_path) goto out; snprintf(tmp_path, PATH_MAX, "/" DEVICE_VIEW_ROOT "/%s%s", - con->cid, dp_recv->path); + con->cid, dp_recv->path); err = vfs_path_lookup(root_path.dentry, root_path.mnt, tmp_path, 0, - &path); - if (err) { + &path); + if (err) + { hmdfs_info("path found failed err = %d", err); goto free; } @@ -2123,3 +2322,91 @@ void hmdfs_server_get_drop_push(struct hmdfs_peer *con, quickack: set_conn_sock_quickack(con); } + +static struct drop_page_push_recv init_drop_page_push_recv(void *data) +{ + struct drop_page_push_request *dpp_recv = data; + struct drop_page_push_recv dppr = { + .file_size = le64_to_cpu(dpp_recv->file_size), + .path_len = le32_to_cpu(dpp_recv->path_len), + .buf = dpp_recv->buf, + }; + dppr.remote_ctime.tv_sec = le64_to_cpu(dpp_recv->ctime); + dppr.remote_ctime.tv_nsec = le64_to_cpu(dpp_recv->ctime_nsec); + dppr.stable_ctime.tv_sec = le64_to_cpu(dpp_recv->stable_ctime); + dppr.stable_ctime.tv_nsec = le64_to_cpu(dpp_recv->stable_ctime_nsec); + + return dppr; +} + +void hmdfs_server_get_drop_page_push(struct hmdfs_peer *con, + struct hmdfs_head_cmd *cmd, void *data) +{ + struct drop_page_push_recv dpp_recv = init_drop_page_push_recv(data); + struct path root_path, path; + struct inode *inode; + struct hmdfs_inode_info *info; + char *tmp_path = NULL; + int err; + + // Learn from hmdfs_server_get_drop_push + const char *root_name = con->sbi->real_dst; + if (path_contain_dotdot(dpp_recv.buf, dpp_recv.path_len)) + { + err = -EINVAL; + goto quickack; + } + + err = kern_path(root_name, 0, &root_path); + if (err) + { + hmdfs_err("kern_path failed at %s, err = %d", root_name, err); + goto quickack; + } + + tmp_path = kzalloc(PATH_MAX, GFP_KERNEL); + if (!tmp_path) + goto out_kfree; + snprintf(tmp_path, PATH_MAX, "/" DEVICE_VIEW_ROOT "/%s%s", + con->cid, dpp_recv.buf); + + err = vfs_path_lookup(root_path.dentry, root_path.mnt, tmp_path, 0, + &path); + if (err) + { + hmdfs_info("path found failed at %s, err = %d", dpp_recv.buf, err); + goto out_tfree; + } + + inode = d_inode(path.dentry); + info = hmdfs_i(inode); + + inode_lock(inode); + + /* + * It doesn't make sense to update metadata here but leaving the data obsolete. + * But how to design here? Should we also transport the data here? + * Transporting data means we may never open the file twice, + * which may corrupt file reference counter in server when the file is not opened but the page cache is missing. + */ + // inode->i_ctime = dpp_recv.remote_ctime; + // info->remote_ctime = dpp_recv.remote_ctime; + // info->stable_ctime = dpp_recv.stable_ctime; + + // i_size_write(inode, dpp_recv.file_size); + + info->need_reopen = true; + + inode_unlock(inode); + + path_put(&path); + +out_tfree: + kfree(tmp_path); + +out_kfree: + path_put(&root_path); + +quickack: + set_conn_sock_quickack(con); +} diff --git a/fs/hmdfs/hmdfs_server.h b/fs/hmdfs/hmdfs_server.h index e832c7ff85be..cab043009c80 100644 --- a/fs/hmdfs/hmdfs_server.h +++ b/fs/hmdfs/hmdfs_server.h @@ -20,6 +20,15 @@ #define DATA_SEC_LEVEL_LABEL "user.security" #define DATA_SEC_LEVEL_LENGTH 10 +struct drop_page_push_recv +{ + __u64 file_size; + struct hmdfs_time_t remote_ctime; + struct hmdfs_time_t stable_ctime; + __u32 path_len; + char *buf; +}; + static inline void hmdfs_send_err_response(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, int err) { @@ -74,6 +83,8 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, void *data); void hmdfs_server_get_drop_push(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, void *data); +void hmdfs_server_get_drop_page_push(struct hmdfs_peer *con, + struct hmdfs_head_cmd *cmd, void *data); void __init hmdfs_server_add_node_evt_cb(void); #endif diff --git a/fs/hmdfs/inode.h b/fs/hmdfs/inode.h index fb9bd2929d58..ddb14f127851 100644 --- a/fs/hmdfs/inode.h +++ b/fs/hmdfs/inode.h @@ -69,6 +69,9 @@ struct hmdfs_inode_info { struct inode *lower_inode; // for local/merge inode struct hmdfs_peer *conn; // for remote inode struct kref ref; + bool need_reopen; + spinlock_t modify_lock; + bool modified; spinlock_t fid_lock; struct hmdfs_fid fid; unsigned long fid_flags; diff --git a/fs/hmdfs/inode_local.c b/fs/hmdfs/inode_local.c index da1db4cbc7c5..617d73eb696e 100644 --- a/fs/hmdfs/inode_local.c +++ b/fs/hmdfs/inode_local.c @@ -41,7 +41,7 @@ int init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry, INIT_LIST_HEAD(&info->cache_list_head); INIT_LIST_HEAD(&info->remote_cache_list_head); spin_lock_init(&info->cache_list_lock); - mutex_init(&info->remote_cache_list_lock); + spin_lock_init(&info->remote_cache_list_lock); mutex_init(&info->cache_pull_lock); spin_lock_init(&info->lock); info->dentry_type = dentry_type; @@ -455,6 +455,8 @@ int hmdfs_create_local_dentry(struct inode *dir, struct dentry *dentry, d_add(dentry, child_inode); out_created: + // It seems that we should use local_view here + // i.e. /mnt/hmdfs//account/device_view/local/data// hmdfs_drop_remote_cache_dents(dentry->d_parent); out: if (error) { diff --git a/fs/hmdfs/main.c b/fs/hmdfs/main.c index 10d37cbac2ef..5e3f7bacda48 100644 --- a/fs/hmdfs/main.c +++ b/fs/hmdfs/main.c @@ -314,6 +314,9 @@ static struct inode *hmdfs_alloc_inode(struct super_block *sb) if (!gi) return NULL; memset(gi, 0, offsetof(struct hmdfs_inode_info, vfs_inode)); + gi->need_reopen = true; + gi->modified = false; + spin_lock_init(&gi->modify_lock); INIT_LIST_HEAD(&gi->wb_list); init_rwsem(&gi->wpage_sem); gi->getattr_isize = HMDFS_STALE_REMOTE_ISIZE; @@ -697,6 +700,7 @@ static void hmdfs_init_cmd_timeout(struct hmdfs_sb_info *sbi) set_cmd_timeout(sbi, F_STATFS, TIMEOUT_COMMON); set_cmd_timeout(sbi, F_CONNECT_REKEY, TIMEOUT_NONE); set_cmd_timeout(sbi, F_DROP_PUSH, TIMEOUT_NONE); + set_cmd_timeout(sbi, F_DROP_PAGE_PUSH, TIMEOUT_NONE); set_cmd_timeout(sbi, F_GETATTR, TIMEOUT_COMMON); set_cmd_timeout(sbi, F_FSYNC, TIMEOUT_90S); set_cmd_timeout(sbi, F_SYNCFS, TIMEOUT_30S); -- Gitee From 073ca71eff8dc00ea61a59d7b5f7833c6e351cec Mon Sep 17 00:00:00 2001 From: Jingyao Zeng Date: Thu, 10 Apr 2025 19:19:25 +0800 Subject: [PATCH 2/3] chore: reformat code Signed-off-by: Jingyao Zeng --- fs/hmdfs/comm/device_node.c | 18 ++++++++++-------- fs/hmdfs/comm/message_verify.c | 3 ++- fs/hmdfs/comm/protocol.h | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/fs/hmdfs/comm/device_node.c b/fs/hmdfs/comm/device_node.c index 63b8a619d980..f4155848e33c 100644 --- a/fs/hmdfs/comm/device_node.c +++ b/fs/hmdfs/comm/device_node.c @@ -1343,16 +1343,18 @@ HMDFS_CMD_ATTR(listxattr, F_LISTXATTR); #define ATTR_LIST(_name) (&hmdfs_attr_##_name.attr) static struct attribute *sbi_timeout_attrs[] = { - ATTR_LIST(open), ATTR_LIST(release), + ATTR_LIST(open), ATTR_LIST(release), ATTR_LIST(readpage), ATTR_LIST(writepage), - ATTR_LIST(iterate), ATTR_LIST(rmdir), - ATTR_LIST(unlink), ATTR_LIST(rename), - ATTR_LIST(setattr), ATTR_LIST(statfs), - ATTR_LIST(drop_push), ATTR_LIST(drop_page_push), - ATTR_LIST(getattr), ATTR_LIST(fsync), - ATTR_LIST(syncfs), ATTR_LIST(getxattr), + ATTR_LIST(iterate), ATTR_LIST(rmdir), + ATTR_LIST(unlink), ATTR_LIST(rename), + ATTR_LIST(setattr), + ATTR_LIST(statfs), ATTR_LIST(drop_push), + ATTR_LIST(getattr), ATTR_LIST(fsync), + ATTR_LIST(syncfs), ATTR_LIST(getxattr), ATTR_LIST(setxattr), ATTR_LIST(listxattr), - NULL}; + ATTR_LIST(drop_page_push), + NULL +}; static const struct sysfs_ops sbi_cmd_sysfs_ops = { .show = cmd_timeout_show, diff --git a/fs/hmdfs/comm/message_verify.c b/fs/hmdfs/comm/message_verify.c index b3ae61a2d267..65711424583a 100644 --- a/fs/hmdfs/comm/message_verify.c +++ b/fs/hmdfs/comm/message_verify.c @@ -949,7 +949,8 @@ static void handle_bad_message(struct hmdfs_peer *con, bool is_reserved_command(int command) { if ((command >= F_RESERVED_1 && command <= F_RESERVED_4) || - command == F_RESERVED_5 || command == F_RESERVED_7 || command == F_RESERVED_8) + command == F_RESERVED_5 || command == F_RESERVED_6 || + command == F_RESERVED_7 || command == F_RESERVED_8) return true; return false; } diff --git a/fs/hmdfs/comm/protocol.h b/fs/hmdfs/comm/protocol.h index aebb6c7dc4b2..29c65a791c69 100644 --- a/fs/hmdfs/comm/protocol.h +++ b/fs/hmdfs/comm/protocol.h @@ -174,7 +174,7 @@ enum FILE_CMD F_STATFS = 16, F_CONNECT_REKEY = 17, F_DROP_PUSH = 18, - F_DROP_PAGE_PUSH = 19, + F_RESERVED_6 = 19, F_GETATTR = 20, F_FSYNC = 21, F_SYNCFS = 22, @@ -184,6 +184,7 @@ enum FILE_CMD F_RESERVED_7 = 26, F_RESERVED_8 = 27, F_ATOMIC_OPEN = 28, + F_DROP_PAGE_PUSH = 29, F_SIZE, }; -- Gitee From 8ff05de3b554c7d3b3c7b73372dcdf8f72b279a3 Mon Sep 17 00:00:00 2001 From: Jingyao Zeng Date: Wed, 23 Apr 2025 10:51:01 +0800 Subject: [PATCH 3/3] feat: compatible with old versions Signed-off-by: Jingyao Zeng --- fs/hmdfs/comm/message_verify.c | 7 +- fs/hmdfs/comm/protocol.h | 17 +- fs/hmdfs/file_local.c | 5 +- fs/hmdfs/file_remote.c | 55 +-- fs/hmdfs/hmdfs_client.c | 26 +- fs/hmdfs/hmdfs_client.h | 2 +- fs/hmdfs/hmdfs_dentryfile.c | 71 ++- fs/hmdfs/hmdfs_device_view.h | 2 +- fs/hmdfs/hmdfs_server.c | 799 +++++++++++++-------------------- fs/hmdfs/hmdfs_server.h | 5 +- fs/hmdfs/inode_local.c | 2 +- 11 files changed, 407 insertions(+), 584 deletions(-) diff --git a/fs/hmdfs/comm/message_verify.c b/fs/hmdfs/comm/message_verify.c index 65711424583a..19514a8cf0ee 100644 --- a/fs/hmdfs/comm/message_verify.c +++ b/fs/hmdfs/comm/message_verify.c @@ -44,11 +44,12 @@ void hmdfs_message_verify_init(void) sizeof(struct open_request) + PATH_MAX + 1; message_length[C_REQUEST][F_OPEN][HMDFS_MESSAGE_LEN_JUDGE_INDEX] = MESSAGE_LEN_JUDGE_RANGE; - message_length[C_RESPONSE][F_OPEN][HMDFS_MESSAGE_MIN_INDEX] = 0; + message_length[C_RESPONSE][F_OPEN][HMDFS_MESSAGE_MIN_INDEX] = sizeof( + struct open_response) - HMDFS_PAGE_SIZE - 1; message_length[C_RESPONSE][F_OPEN][HMDFS_MESSAGE_MAX_INDEX] = sizeof(struct open_response); message_length[C_RESPONSE][F_OPEN][HMDFS_MESSAGE_LEN_JUDGE_INDEX] = - MESSAGE_LEN_JUDGE_BIN; + MESSAGE_LEN_JUDGE_RANGE; message_length[C_REQUEST][F_ATOMIC_OPEN][HMDFS_MESSAGE_MIN_INDEX] = sizeof(struct atomic_open_request); @@ -316,7 +317,7 @@ static int verify_open_resp(size_t msg_len, void *msg) { struct open_response *resp = msg; - if (msg_len != sizeof(*resp)) + if (msg_len != sizeof(*resp) && msg_len != sizeof(*resp) - HMDFS_PAGE_SIZE - 1) return -EINVAL; return 0; diff --git a/fs/hmdfs/comm/protocol.h b/fs/hmdfs/comm/protocol.h index 29c65a791c69..a8e795e04739 100644 --- a/fs/hmdfs/comm/protocol.h +++ b/fs/hmdfs/comm/protocol.h @@ -13,6 +13,8 @@ #include #include +#define HMDFS_PREFETCH_FLAG 00000001 + struct hmdfs_cmd { __u8 reserved; __u8 cmd_flag; @@ -20,6 +22,16 @@ struct hmdfs_cmd { __u8 reserved2; } __packed; +static inline bool hm_isprefetch(__u8 flag) +{ + return (flag & HMDFS_PREFETCH_FLAG) == HMDFS_PREFETCH_FLAG; +} + +static inline void hm_setprefetch(__u8* flag) +{ + *flag |= HMDFS_PREFETCH_FLAG; +} + #define HMDFS_MSG_MAGIC 0xF7 #define HMDFS_MAX_MESSAGE_LEN (8 * 1024 * 1024) @@ -153,8 +165,7 @@ enum DFS_VERSION { enum CMD_FLAG { C_REQUEST = 0, C_RESPONSE = 1, C_FLAG_SIZE }; -enum FILE_CMD -{ +enum FILE_CMD { F_OPEN = 0, F_RELEASE = 1, F_READPAGE = 2, @@ -338,7 +349,7 @@ struct drop_push_request { char path[0]; } __packed; -struct drop_page_push_request{ +struct drop_page_push_request { __le64 file_size; __le64 ctime; __le32 ctime_nsec; diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index 96072d260aa9..6f12f2a867aa 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -66,8 +66,7 @@ int hmdfs_file_release_local(struct inode *inode, struct file *file) atomic_dec(&info->write_opened); spin_lock(&info->modify_lock); - if (info->modified) - { + if (info->modified){ hmdfs_drop_remote_cache_pages(file_dentry(file)); info->modified = false; } @@ -140,7 +139,7 @@ static void hmdfs_file_modified(struct file *file) } ssize_t hmdfs_do_write_iter_local(struct file *file, struct iov_iter *iter, - loff_t *ppos) + loff_t *ppos) { ssize_t ret; struct file *lower_file = hmdfs_f(file)->lower_file; diff --git a/fs/hmdfs/file_remote.c b/fs/hmdfs/file_remote.c index 36e42bb7637a..1a840b8e41fd 100644 --- a/fs/hmdfs/file_remote.c +++ b/fs/hmdfs/file_remote.c @@ -184,24 +184,20 @@ int hmdfs_do_open_remote(struct inode *inode, struct file *file, bool keep_cache } err = hmdfs_open_final_remote(info, &open_ret, file, keep_cache); - if (err) - { + if (err) { hmdfs_err("hmdfs_open_final_remote return failed with %d", err); goto out_free; } struct page *page = grab_cache_page(inode->i_mapping, 0); - if (!IS_ERR(page)) - { - if (open_ret.read_success) - { + if (!IS_ERR(page)) { + if (open_ret.read_success == 1) { hmdfs_set_page_content(page, open_ret.page); unlock_page(page); - } - else - { + } else { unlock_page(page); put_page(page); + err = open_ret.read_success; } } @@ -370,43 +366,37 @@ int hmdfs_file_open_remote(struct inode *inode, struct file *file) // NB: we only consider small file (size <= 1 KiB) here, otherwise we may need handle reading uncached pages when the file is not actually opened if (kref_read(ref) == 0) { // If the file is opened with intent to be modified, then we must communicate with the file holder - if ((file->f_flags & O_ACCMODE) == O_RDONLY) - { - if (info->need_reopen) - { + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if (info->need_reopen) { err = hmdfs_do_open_remote(inode, file, false); - if (err == 0) - { + if (err >= 0) { kref_init(ref); - info->need_reopen = false; + info->need_reopen = err == EOPNOTSUPP? true : false; + err = 0; } - } - else - { - if (info->writecache_expire && hmdfs_remote_write_cache_expired(info)) - { + } else { + if (info->writecache_expire && hmdfs_remote_write_cache_expired(info)) { // different from above situation, here we set writecache_expire to 0, and truncate the inode page // because we can omit the repeated judgement in hmdfs_open_final_remote info->writecache_expire = 0; truncate_inode_pages(inode->i_mapping, 0); err = hmdfs_do_open_remote(inode, file, false); - if (err == 0) + if (err >= 0) { kref_init(ref); - } - else - { + info->need_reopen = err == EOPNOTSUPP? true : false; + err = 0; + } + } else { atomic64_set(&info->write_counter, 0); info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE; } } - } - else - { + } else { err = hmdfs_do_open_remote(inode, file, false); - if (err == 0) - { + if (err >= 0) { kref_init(ref); - info->need_reopen = false; + info->need_reopen = err == EOPNOTSUPP? true : false; + err = 0; } } } else { @@ -495,9 +485,8 @@ int hmdfs_file_release_remote(struct inode *inode, struct file *file) inode_lock(inode); if (kref_read(&info->ref) > 0) - { kref_put(&info->ref, hmdfs_do_close_remote); - } + hmdfs_remote_keep_writecache(inode, file); inode_unlock(inode); diff --git a/fs/hmdfs/hmdfs_client.c b/fs/hmdfs/hmdfs_client.c index 17ee4b8bca06..295c9297ca71 100644 --- a/fs/hmdfs/hmdfs_client.c +++ b/fs/hmdfs/hmdfs_client.c @@ -52,7 +52,7 @@ static struct hmdfs_time_t hmdfs_current_kernel_time(void) } int hmdfs_send_open(struct hmdfs_peer *con, const char *send_buf, - __u8 file_type, struct hmdfs_open_ret *open_ret) + __u8 file_type, struct hmdfs_open_ret *open_ret) { int ret; int path_len = strlen(send_buf); @@ -66,6 +66,7 @@ int hmdfs_send_open(struct hmdfs_peer *con, const char *send_buf, .local_filp = NULL, }; hmdfs_init_cmd(&sm.operations, F_OPEN); + hm_setprefetch(&sm.operations.reserved); if (!open_req) { ret = -ENOMEM; @@ -91,9 +92,13 @@ int hmdfs_send_open(struct hmdfs_peer *con, const char *send_buf, open_ret->remote_ctime.tv_nsec = le32_to_cpu(resp->ctime_nsec); open_ret->stable_ctime.tv_sec = le64_to_cpu(resp->stable_ctime); open_ret->stable_ctime.tv_nsec = le32_to_cpu(resp->stable_ctime_nsec); - open_ret->read_success = resp->read_success; - if (open_ret->read_success) - memcpy(open_ret->page, resp->page, HMDFS_PAGE_SIZE); + if(sm.out_len == sizeof(struct open_response)) { + open_ret->read_success = resp->read_success; + if (open_ret->read_success) + memcpy(open_ret->page, resp->page, HMDFS_PAGE_SIZE); + } else { + open_ret->read_success = EOPNOTSUPP; + } out: free_sm_outbuf(&sm); @@ -1100,19 +1105,14 @@ void hmdfs_send_drop_page_push(struct hmdfs_peer *con, const char *send_buf, str dpp_req->ctime_nsec = cpu_to_le32(ctime.tv_nsec); precision = hmdfs_time_add(ctime, precision); - if (hmdfs_time_compare(¤t_time, &ctime) < 0) - { + if (hmdfs_time_compare(¤t_time, &ctime) < 0) { dpp_req->stable_ctime = cpu_to_le64(0); dpp_req->stable_ctime_nsec = cpu_to_le32(0); - } - else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && - hmdfs_time_compare(¤t_time, &precision) < 0) - { + } else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && + hmdfs_time_compare(¤t_time, &precision) < 0) { dpp_req->stable_ctime = dpp_req->ctime; dpp_req->stable_ctime_nsec = dpp_req->ctime_nsec; - } - else - { + } else { dpp_req->stable_ctime = cpu_to_le64(precision.tv_sec); dpp_req->stable_ctime_nsec = cpu_to_le32(precision.tv_nsec); } diff --git a/fs/hmdfs/hmdfs_client.h b/fs/hmdfs/hmdfs_client.h index e85e82c11a5e..25cda9b3ffba 100644 --- a/fs/hmdfs/hmdfs_client.h +++ b/fs/hmdfs/hmdfs_client.h @@ -92,7 +92,7 @@ void hmdfs_client_writepage_done(struct hmdfs_inode_info *info, struct hmdfs_writepage_context *ctx); int hmdfs_send_open(struct hmdfs_peer *con, const char *send_buf, - __u8 file_type, struct hmdfs_open_ret *open_ret); + __u8 file_type, struct hmdfs_open_ret *open_ret); void hmdfs_send_close(struct hmdfs_peer *con, const struct hmdfs_fid *fid); int hmdfs_send_fsync(struct hmdfs_peer *con, const struct hmdfs_fid *fid, __s64 start, __s64 end, __s32 datasync); diff --git a/fs/hmdfs/hmdfs_dentryfile.c b/fs/hmdfs/hmdfs_dentryfile.c index e42cbe436c3d..4c528ab20feb 100644 --- a/fs/hmdfs/hmdfs_dentryfile.c +++ b/fs/hmdfs/hmdfs_dentryfile.c @@ -212,13 +212,6 @@ static char *hmdfs_dentry_path_raw(struct dentry *d, char *buf, int buflen) read_seqbegin_or_lock(&rename_lock, &seq); while (di->dentry_type != hmdfs_root_dentry_type) { struct dentry *parent = dentry->d_parent; - /* Not sure whether it should be this */ - // if (!parent) - // { - // hmdfs_err("parent is NULL"); - // error = -EINVAL; - // break; - // } prefetch(parent); error = prepend_name(&end, &len, &dentry->d_name); @@ -2356,11 +2349,11 @@ void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path) } /* find duplicate con */ - spin_lock(&d_info->remote_cache_list_lock); + mutex_lock(&d_info->remote_cache_list_lock); list_for_each_entry_safe(item, item_temp, &(d_info->remote_cache_list_head), list) { if (item->con->device_id == con->device_id) { - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); goto out; } } @@ -2368,14 +2361,14 @@ void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path) item = kzalloc(sizeof(*item), GFP_KERNEL); if (!item) { err = -ENOMEM; - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); goto out; } item->con = con; item->drop_flag = 0; list_add(&(item->list), &(d_info->remote_cache_list_head)); - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); out: path_put(&path); @@ -2394,28 +2387,25 @@ void hmdfs_add_remote_page_cache_list(struct hmdfs_peer *con, struct file *file) return; /* find duplicate con */ - spin_lock(&d_info->remote_cache_list_lock); + mutex_lock(&d_info->remote_cache_list_lock); list_for_each_entry_safe(item, item_temp, - &(d_info->remote_cache_list_head), list) - { - if (item->con->device_id == con->device_id) - { - spin_unlock(&d_info->remote_cache_list_lock); + &(d_info->remote_cache_list_head), list) { + if (item->con->device_id == con->device_id) { + mutex_unlock(&d_info->remote_cache_list_lock); return; } } item = kzalloc(sizeof(*item), GFP_KERNEL); - if (!item) - { - spin_unlock(&d_info->remote_cache_list_lock); + if (!item) { + mutex_unlock(&d_info->remote_cache_list_lock); return; } item->con = con; item->drop_flag = 0; list_add(&(item->list), &(d_info->remote_cache_list_head)); - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); } int hmdfs_drop_remote_cache_dents(struct dentry *dentry) @@ -2455,20 +2445,20 @@ int hmdfs_drop_remote_cache_dents(struct dentry *dentry) hmdfs_err("get dentry relative path failed"); return 0; } - spin_lock(&d_info->remote_cache_list_lock); + mutex_lock(&d_info->remote_cache_list_lock); list_for_each_entry_safe(item, item_temp, &(d_info->remote_cache_list_head), list) { if (item->drop_flag) { item->drop_flag = 0; continue; } - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); hmdfs_send_drop_push(item->con, relative_path); - spin_lock(&d_info->remote_cache_list_lock); + mutex_lock(&d_info->remote_cache_list_lock); list_del(&item->list); kfree(item); } - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); kfree(relative_path); return 0; @@ -2481,38 +2471,33 @@ int hmdfs_drop_remote_cache_pages(struct dentry *dentry) struct hmdfs_dentry_info *d_info = NULL; char *relative_path = NULL; - if (!dentry) - { + if (!dentry) { hmdfs_err("dentry null and return"); return 0; } d_info = hmdfs_d(dentry); - if (!d_info) - { + if (!d_info) { hmdfs_err("d_info null and return"); return 0; } relative_path = hmdfs_get_dentry_relative_path(dentry); - if (!relative_path) - { + if (!relative_path) { hmdfs_err("get dentry relative path failed"); return 0; } - spin_lock(&d_info->remote_cache_list_lock); + mutex_lock(&d_info->remote_cache_list_lock); list_for_each_entry_safe(item, item_temp, - &(d_info->remote_cache_list_head), list) - { - if (item->drop_flag == 1) - { + &(d_info->remote_cache_list_head), list) { + if (item->drop_flag == 1) { item->drop_flag = 0; continue; } - spin_unlock(&d_info->remote_cache_list_lock); hmdfs_send_drop_page_push(item->con, relative_path, dentry->d_inode); - spin_lock(&d_info->remote_cache_list_lock); + list_del(&item->list); + kfree(item); } - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); kfree(relative_path); return 0; @@ -2567,14 +2552,14 @@ void hmdfs_mark_drop_flag(uint64_t device_id, struct dentry *dentry) return; } - spin_lock(&d_info->remote_cache_list_lock); + mutex_lock(&d_info->remote_cache_list_lock); list_for_each_entry(item, &(d_info->remote_cache_list_head), list) { if (item->con->device_id == device_id) { item->drop_flag = 1; break; } } - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); } void hmdfs_clear_drop_flag(struct dentry *dentry) @@ -2593,12 +2578,12 @@ void hmdfs_clear_drop_flag(struct dentry *dentry) return; } - spin_lock(&d_info->remote_cache_list_lock); + mutex_lock(&d_info->remote_cache_list_lock); list_for_each_entry(item, &(d_info->remote_cache_list_head), list) { if (item->drop_flag) item->drop_flag = 0; } - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); } #define DUSTBIN_SUFFIX ".hwbk" diff --git a/fs/hmdfs/hmdfs_device_view.h b/fs/hmdfs/hmdfs_device_view.h index f235ec8a2429..d745c321d831 100644 --- a/fs/hmdfs/hmdfs_device_view.h +++ b/fs/hmdfs/hmdfs_device_view.h @@ -50,7 +50,7 @@ struct hmdfs_dentry_info { struct list_head cache_list_head; spinlock_t cache_list_lock; struct list_head remote_cache_list_head; - spinlock_t remote_cache_list_lock; + struct mutex remote_cache_list_lock; __u8 file_type; __u8 dentry_type; uint64_t device_id; diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index 16663dcdb7d5..b50238d47e05 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -21,10 +21,9 @@ #include "server_writeback.h" #include "comm/node_cb.h" -#define HMDFS_MAX_HIDDEN_DIR 1 +#define HMDFS_MAX_HIDDEN_DIR 1 -struct hmdfs_open_info -{ +struct hmdfs_open_info { struct file *file; struct inode *inode; bool stat_valid; @@ -38,8 +37,7 @@ static void find_first_no_slash(const char **name, int *len) const char *s = *name; int l = *len; - while (l > 0 && *s == '/') - { + while (l > 0 && *s == '/') { s++; l--; } @@ -53,8 +51,7 @@ static void find_first_slash(const char **name, int *len) const char *s = *name; int l = *len; - while (l > 0 && *s != '/') - { + while (l > 0 && *s != '/') { s++; l--; } @@ -65,15 +62,14 @@ static void find_first_slash(const char **name, int *len) static bool path_contain_dotdot(const char *name, int len) { - while (true) - { + while (true) { find_first_no_slash(&name, &len); if (len == 0) return false; if (len >= 2 && name[0] == '.' && name[1] == '.' && - (len == 2 || name[2] == '/')) + (len == 2 || name[2] == '/')) return true; find_first_slash(&name, &len); @@ -121,18 +117,15 @@ int remove_file_from_conn(struct hmdfs_peer *conn, __u32 file_id) file = idr_remove(idr, file_id); spin_unlock(lock); - if (!file) - { + if (!file) { return -ENOENT; - } - else - { + } else { return 0; } } struct file *hmdfs_open_link(struct hmdfs_sb_info *sbi, - const char *path) + const char *path) { struct file *file; int err; @@ -141,28 +134,23 @@ struct file *hmdfs_open_link(struct hmdfs_sb_info *sbi, int path_len; path_len = strlen(root_name) + strlen(path) + 2; - if (path_len > PATH_MAX) - { + if (path_len > PATH_MAX) { err = -EINVAL; return ERR_PTR(err); } real_path = kzalloc(path_len, GFP_KERNEL); - if (!real_path) - { + if (!real_path) { err = -ENOMEM; return ERR_PTR(err); } sprintf(real_path, "%s%s", root_name, path); file = filp_open(real_path, O_RDWR | O_LARGEFILE, 0644); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { hmdfs_info("filp_open failed: %ld", PTR_ERR(file)); - } - else - { - hmdfs_info("get file with magic %lu", - file->f_inode->i_sb->s_magic); + } else { + hmdfs_info("get file with magic %lu", + file->f_inode->i_sb->s_magic); } kfree(real_path); @@ -177,25 +165,21 @@ struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) const char *root_name = sbi->local_dst; err = kern_path(root_name, 0, &root_path); - if (err) - { + if (err) { hmdfs_info("kern_path failed: %d", err); return ERR_PTR(err); } file = file_open_root(&root_path, path, - O_RDWR | O_LARGEFILE, 0644); + O_RDWR | O_LARGEFILE, 0644); path_put(&root_path); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { hmdfs_err( "GRAPERR sb->s_readonly_remount %d sb_flag %lu", sbi->sb->s_readonly_remount, sbi->sb->s_flags); hmdfs_info("file_open_root failed: %ld", PTR_ERR(file)); - } - else - { + } else { hmdfs_info("get file with magic %lu", - file->f_inode->i_sb->s_magic); + file->f_inode->i_sb->s_magic); } return file; } @@ -207,7 +191,7 @@ inline void hmdfs_close_path(struct file *file) /* After offline server close all files opened by client */ void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt, - unsigned int seq) + unsigned int seq) { int id; int count = 0; @@ -222,8 +206,7 @@ void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt, /* If there is some open requests in processing, * Maybe, we need to close file when peer offline */ - idr_for_each_entry(idr, filp, id) - { + idr_for_each_entry(idr, filp, id) { hmdfs_debug("[%d]Server close: id=%d", count, id); hmdfs_close_path(filp); count++; @@ -245,9 +228,11 @@ void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt, } static struct hmdfs_node_cb_desc server_cb[] = { - {.evt = NODE_EVT_OFFLINE, - .sync = true, - .fn = hmdfs_server_offline_notify}, + { + .evt = NODE_EVT_OFFLINE, + .sync = true, + .fn = hmdfs_server_offline_notify + }, }; void __init hmdfs_server_add_node_evt_cb(void) @@ -255,8 +240,8 @@ void __init hmdfs_server_add_node_evt_cb(void) hmdfs_node_add_evt_cb(server_cb, ARRAY_SIZE(server_cb)); } -static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, - uint64_t *ino) +static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, + uint64_t *ino) { int ret = 0; struct path root_path; @@ -264,16 +249,14 @@ static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, struct inode *inode = NULL; ret = kern_path(con->sbi->local_dst, 0, &root_path); - if (ret) - { + if (ret) { hmdfs_err("kern_path failed err = %d", ret); return ret; } - ret = vfs_path_lookup(root_path.dentry, root_path.mnt, filename, 0, - &dst_path); - if (ret) - { + ret = vfs_path_lookup(root_path.dentry, root_path.mnt, filename, 0, + &dst_path); + if (ret) { path_put(&root_path); return ret; } @@ -290,14 +273,14 @@ static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, } static const char *datasl_str[] = { - "s0", "s1", "s2", "s3", "s4"}; + "s0", "s1", "s2", "s3", "s4" +}; static int parse_data_sec_level(const char *sl_value, size_t sl_value_len) { int i; - for (i = 0; i < sizeof(datasl_str) / sizeof(datasl_str[0]); i++) - { + for (i = 0; i < sizeof(datasl_str) / sizeof(datasl_str[0]); i++) { if (!strncmp(sl_value, datasl_str[i], strlen(datasl_str[i]))) return i + DATA_SEC_LEVEL0; } @@ -314,38 +297,34 @@ static int check_sec_level(struct hmdfs_peer *node, const char *file_name) char *value = NULL; size_t value_len = DATA_SEC_LEVEL_LENGTH; - if (node->devsl <= 0) - { + if (node->devsl <= 0) { ret = -EACCES; goto out_free; } value = kzalloc(value_len, GFP_KERNEL); - if (!value) - { + if (!value) { ret = -ENOMEM; goto out_free; } err = kern_path(node->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) - { + if (err) { hmdfs_err("get root path error"); ret = err; goto out_free; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, file_name, 0, - &file_path); - if (err) - { + &file_path); + if (err) { hmdfs_err("get file path error"); ret = err; goto out_err; } err = vfs_getxattr(file_path.dentry, DATA_SEC_LEVEL_LABEL, value, - value_len); + value_len); if (err <= 0 && node->devsl >= DATA_SEC_LEVEL3) goto out; if (err > 0 && node->devsl >= parse_data_sec_level(value, err)) @@ -362,29 +341,26 @@ static int check_sec_level(struct hmdfs_peer *node, const char *file_name) } static struct file *hmdfs_open_file(struct hmdfs_peer *con, - const char *filename, uint8_t file_type, - int *file_id) + const char *filename, uint8_t file_type, + int *file_id) { struct file *file = NULL; int err = 0; int id; - if (!filename) - { + if (!filename) { hmdfs_err("filename is NULL"); return ERR_PTR(-EINVAL); } - if (check_sec_level(con, filename)) - { + if (check_sec_level(con, filename)) { hmdfs_err("devsl permission denied"); return ERR_PTR(-EACCES); } - if (hm_isshare(file_type)) - { + if (hm_isshare(file_type)) { err = hmdfs_check_share_access_permission(con->sbi, - filename, con->cid); + filename, con->cid); if (err) return ERR_PTR(err); } @@ -394,16 +370,14 @@ static struct file *hmdfs_open_file(struct hmdfs_peer *con, else file = hmdfs_open_path(con->sbi, filename); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { reset_item_opened_status(con->sbi, filename); return file; } get_file(file); id = insert_file_into_conn(con, file); - if (id < 0) - { + if (id < 0) { hmdfs_err("file_id alloc failed! err=%d", id); reset_item_opened_status(con->sbi, filename); hmdfs_close_path(file); @@ -445,26 +419,25 @@ static struct hmdfs_time_t hmdfs_current_kernel_time(void) * 49 15 (bits) */ static uint64_t hmdfs_server_pack_fid_ver(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd) + struct hmdfs_head_cmd *cmd) { uint64_t boot_cookie = con->sbi->boot_cookie; uint16_t con_cookie = con->fid_cookie; return (boot_cookie | - (con_cookie & ((1 << HMDFS_FID_VER_BOOT_COOKIE_SHIFT) - 1))); + (con_cookie & ((1 << HMDFS_FID_VER_BOOT_COOKIE_SHIFT) - 1))); } static struct file *get_file_by_fid_and_ver(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, - __u32 file_id, __u64 file_ver) + struct hmdfs_head_cmd *cmd, + __u32 file_id, __u64 file_ver) { struct file *file = NULL; __u64 cur_file_ver = hmdfs_server_pack_fid_ver(con, cmd); - if (file_ver != cur_file_ver) - { + if (file_ver != cur_file_ver) { hmdfs_warning("Stale file version %llu for fid %u", - file_ver, file_id); + file_ver, file_id); return ERR_PTR(-EBADF); } @@ -476,15 +449,19 @@ static struct file *get_file_by_fid_and_ver(struct hmdfs_peer *con, } static void hmdfs_update_open_response(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, - struct hmdfs_open_info *info, - struct open_response *resp) + struct hmdfs_head_cmd *cmd, + struct hmdfs_open_info *info, + struct open_response *resp) { struct hmdfs_time_t current_time = hmdfs_current_kernel_time(); - struct hmdfs_time_t ctime = info->stat_valid ? info->stat.ctime : info->inode->i_ctime; + struct hmdfs_time_t ctime = info->stat_valid ? info->stat.ctime : + info->inode->i_ctime; struct hmdfs_time_t precision = msec_to_timespec(con->sbi->dcache_precision); - loff_t size = info->stat_valid ? info->stat.size : i_size_read(info->inode); + loff_t size = info->stat_valid ? info->stat.size : + i_size_read(info->inode); + loff_t pos = 0; + ssize_t readsize = 0; // NB: info->real_ino is the lower_file's i_ino and i_igeneration, not the info->file's resp->ino = cpu_to_le64(info->real_ino); @@ -503,39 +480,42 @@ static void hmdfs_update_open_response(struct hmdfs_peer *con, * - else, stable_ctime = ctime + dcache_precision; */ precision = hmdfs_time_add(ctime, precision); - if (hmdfs_time_compare(¤t_time, &ctime) < 0) - { + if (hmdfs_time_compare(¤t_time, &ctime) < 0) { resp->stable_ctime = cpu_to_le64(0); resp->stable_ctime_nsec = cpu_to_le32(0); - } - else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && - hmdfs_time_compare(¤t_time, &precision) < 0) - { + } else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && + hmdfs_time_compare(¤t_time, &precision) < 0) { resp->stable_ctime = resp->ctime; resp->stable_ctime_nsec = resp->ctime_nsec; - } - else - { + } else { resp->stable_ctime = cpu_to_le64(precision.tv_sec); resp->stable_ctime_nsec = cpu_to_le32(precision.tv_nsec); } + + if(hm_isprefetch(cmd->operations.reserved)) { + readsize = kernel_read(info->file, resp->page, HMDFS_PAGE_SIZE, &pos); + if (readsize < 0) { + resp->read_success = 0; + } else { + resp->read_success = 1; + if (readsize != HMDFS_PAGE_SIZE) + memset(resp->page + readsize, 0, HMDFS_PAGE_SIZE - readsize); + } + } } static int hmdfs_get_open_info(struct hmdfs_peer *con, uint8_t file_type, - const char *filename, - struct hmdfs_open_info *info) + const char *filename, + struct hmdfs_open_info *info) { int ret = 0; info->inode = file_inode(info->file); info->stat_valid = false; - if (con->sbi->sb == info->inode->i_sb) - { + if (con->sbi->sb == info->inode->i_sb) { /* if open a regular file */ info->inode = hmdfs_i(info->inode)->lower_inode; - } - else if (con->sbi->lower_sb != info->inode->i_sb) - { + } else if (con->sbi->lower_sb != info->inode->i_sb) { /* It's possible that inode is not from lower, for example: * 1. touch /f2fs/file * 2. ln -s /sdcard_fs/file /f2fs/link @@ -549,50 +529,43 @@ static int hmdfs_get_open_info(struct hmdfs_peer *con, uint8_t file_type, * information. */ ret = vfs_getattr(&info->file->f_path, &info->stat, STATX_BASIC_STATS | STATX_BTIME, - 0); - if (ret) - { + 0); + if (ret) { hmdfs_err("call vfs_getattr failed, err %d", ret); return ret; } info->stat_valid = true; } - if (hm_islnk(file_type)) - { + if (hm_islnk(file_type)) { ret = hmdfs_get_inode_by_name(con, filename, &info->real_ino); if (ret) return ret; - } - else - { + } else { info->real_ino = generate_u64_ino(info->inode->i_ino, - info->inode->i_generation); + info->inode->i_generation); } return 0; } static int hmdfs_check_and_create(struct path *path_parent, - struct dentry *dentry, uint64_t device_id, - umode_t mode, bool is_excl) + struct dentry *dentry, uint64_t device_id, + umode_t mode, bool is_excl) { int err = 0; /* if inode doesn't exist, create it */ - if (d_is_negative(dentry)) - { + if (d_is_negative(dentry)) { hmdfs_mark_drop_flag(device_id, path_parent->dentry); err = vfs_create(d_inode(path_parent->dentry), dentry, mode, - is_excl); + is_excl); if (err) hmdfs_err("create failed, err %d", err); - } - else - { + } else { if (is_excl) err = -EEXIST; else if (S_ISREG(d_inode(dentry)->i_mode) && - hm_islnk(hmdfs_d(dentry)->file_type)) + hm_islnk(hmdfs_d(dentry)->file_type)) err = -EINVAL; else if (S_ISDIR(d_inode(dentry)->i_mode)) err = -EISDIR; @@ -601,8 +574,8 @@ static int hmdfs_check_and_create(struct path *path_parent, return err; } static int hmdfs_lookup_create(struct hmdfs_peer *con, - struct atomic_open_request *recv, - struct path *child_path, bool *truncate) + struct atomic_open_request *recv, + struct path *child_path, bool *truncate) { int err = 0; struct path path_root; @@ -613,24 +586,21 @@ static int hmdfs_lookup_create(struct hmdfs_peer *con, struct dentry *dentry = NULL; err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &path_root); - if (err) - { + if (err) { hmdfs_err("no path for %s, err %d", con->sbi->local_dst, err); return err; } err = vfs_path_lookup(path_root.dentry, path_root.mnt, path, - LOOKUP_DIRECTORY, &path_parent); - if (err) - { + LOOKUP_DIRECTORY, &path_parent); + if (err) { hmdfs_info("no dir in %s, err %d", con->sbi->local_dst, err); goto put_path_root; } inode_lock(d_inode(path_parent.dentry)); dentry = lookup_one_len(filename, path_parent.dentry, strlen(filename)); - if (IS_ERR(dentry)) - { + if (IS_ERR(dentry)) { err = PTR_ERR(dentry); inode_unlock(d_inode(path_parent.dentry)); goto put_path_parent; @@ -638,15 +608,12 @@ static int hmdfs_lookup_create(struct hmdfs_peer *con, /* only truncate if inode already exists */ *truncate = ((open_flags & HMDFS_O_TRUNC) && d_is_positive(dentry)); err = hmdfs_check_and_create(&path_parent, dentry, con->device_id, - le16_to_cpu(recv->mode), - open_flags & HMDFS_O_EXCL); + le16_to_cpu(recv->mode), + open_flags & HMDFS_O_EXCL); inode_unlock(d_inode(path_parent.dentry)); - if (err) - { + if (err) { dput(dentry); - } - else - { + } else { child_path->dentry = dentry; child_path->mnt = mntget(path_parent.mnt); } @@ -659,14 +626,13 @@ static int hmdfs_lookup_create(struct hmdfs_peer *con, } static int hmdfs_dentry_open(struct hmdfs_peer *con, - const struct path *path, - struct hmdfs_open_info *info) + const struct path *path, + struct hmdfs_open_info *info) { int err = 0; info->file = dentry_open(path, O_RDWR | O_LARGEFILE, current_cred()); - if (IS_ERR(info->file)) - { + if (IS_ERR(info->file)) { err = PTR_ERR(info->file); hmdfs_err("open file failed, err %d", err); return err; @@ -674,8 +640,7 @@ static int hmdfs_dentry_open(struct hmdfs_peer *con, get_file(info->file); info->file_id = insert_file_into_conn(con, info->file); - if (info->file_id < 0) - { + if (info->file_id < 0) { err = info->file_id; hmdfs_err("file_id alloc failed! err %d", err); hmdfs_close_path(info->file); @@ -687,10 +652,10 @@ static int hmdfs_dentry_open(struct hmdfs_peer *con, } static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, - struct atomic_open_request *recv, - struct hmdfs_open_info *info, - struct atomic_open_response *resp) + struct hmdfs_head_cmd *cmd, + struct atomic_open_request *recv, + struct hmdfs_open_info *info, + struct atomic_open_response *resp) { struct path child_path; bool truncate = false; @@ -708,11 +673,9 @@ static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, if (err) goto fail_close; - if (truncate) - { + if (truncate) { err = vfs_truncate(&child_path, 0); - if (err) - { + if (err) { hmdfs_err("truncate failed, err %d", err); goto fail_close; } @@ -721,8 +684,7 @@ static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, resp->i_mode = cpu_to_le16(file_inode(info->file)->i_mode); fail_close: - if (err) - { + if (err) { remove_file_from_conn(con, info->file_id); hmdfs_close_path(info->file); hmdfs_close_path(info->file); @@ -733,7 +695,7 @@ static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, } void hmdfs_server_atomic_open(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { int err; struct atomic_open_request *recv = data; @@ -742,21 +704,18 @@ void hmdfs_server_atomic_open(struct hmdfs_peer *con, char *file_path = recv->buf; char *file = recv->buf + recv->path_len + 1; - if (path_contain_dotdot(file_path, recv->path_len)) - { + if (path_contain_dotdot(file_path, recv->path_len)) { err = -EINVAL; goto out; } - if (path_contain_dotdot(file, recv->file_len)) - { + if (path_contain_dotdot(file, recv->file_len)) { err = -EINVAL; goto out; } info = kmalloc(sizeof(*info), GFP_KERNEL); resp = kzalloc(sizeof(*resp), GFP_KERNEL); - if (!resp || !info) - { + if (!resp || !info) { err = -ENOMEM; goto out; } @@ -764,18 +723,14 @@ void hmdfs_server_atomic_open(struct hmdfs_peer *con, err = hmdfs_server_do_atomic_open(con, cmd, recv, info, resp); out: - if (err) - { + if (err) { hmdfs_send_err_response(con, cmd, err); - } - else - { + } else { err = hmdfs_sendmessage_response(con, cmd, sizeof(*resp), resp, - 0); - if (err) - { + 0); + if (err) { hmdfs_err("sending msg response failed, file_id %d, err %d", - info->file_id, err); + info->file_id, err); remove_file_from_conn(con, info->file_id); hmdfs_close_path(info->file); } @@ -785,7 +740,7 @@ void hmdfs_server_atomic_open(struct hmdfs_peer *con, } void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct release_request *release_recv = data; struct file *file = NULL; @@ -796,8 +751,7 @@ void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, file_id = le32_to_cpu(release_recv->file_id); file_ver = le64_to_cpu(release_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { hmdfs_err("cannot find %u", file_id); ret = PTR_ERR(file); goto out; @@ -810,8 +764,7 @@ void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_close_path(file); hmdfs_info("close %u", file_id); ret = remove_file_from_conn(con, file_id); - if (ret) - { + if (ret) { hmdfs_err("cannot find after close %u", file_id); goto out; } @@ -824,7 +777,7 @@ void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct fsync_request *fsync_recv = data; __s32 datasync = le32_to_cpu(fsync_recv->datasync); @@ -838,8 +791,7 @@ void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, file_id = le32_to_cpu(fsync_recv->file_id); file_ver = le64_to_cpu(fsync_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { hmdfs_err("cannot find %u", file_id); ret = PTR_ERR(file); goto out; @@ -855,7 +807,7 @@ void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct readpage_request *readpage_recv = data; __u64 file_ver; @@ -869,8 +821,7 @@ void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, file_id = le32_to_cpu(readpage_recv->file_id); file_ver = le64_to_cpu(readpage_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { hmdfs_info( "file with id %u does not exist, pgindex %llu, devid %llu", file_id, le64_to_cpu(readpage_recv->index), @@ -884,20 +835,16 @@ void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, goto fail_put_file; readpage = kmalloc(read_len, GFP_KERNEL); - if (!readpage) - { + if (!readpage) { ret = -ENOMEM; goto fail_put_file; } pos = (loff_t)le64_to_cpu(readpage_recv->index) << HMDFS_PAGE_OFFSET; ret = kernel_read(file, readpage->buf, read_len, &pos); - if (ret < 0) - { + if (ret < 0) { hmdfs_send_err_response(con, cmd, -EIO); - } - else - { + } else { if (ret != read_len) memset(readpage->buf + ret, 0, read_len - ret); hmdfs_sendmessage_response(con, cmd, read_len, readpage, 0); @@ -914,18 +861,18 @@ void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } static bool need_rebuild_dcache(struct hmdfs_dcache_header *h, - struct hmdfs_time_t time, - unsigned int precision) -{ - struct hmdfs_time_t crtime = {.tv_sec = le64_to_cpu(h->dcache_crtime), - .tv_nsec = le64_to_cpu( - h->dcache_crtime_nsec)}; - struct hmdfs_time_t ctime = {.tv_sec = le64_to_cpu(h->dentry_ctime), - .tv_nsec = le64_to_cpu( - h->dentry_ctime_nsec)}; - struct hmdfs_time_t pre_time = {.tv_sec = precision / MSEC_PER_SEC, - .tv_nsec = precision % MSEC_PER_SEC * - NSEC_PER_MSEC}; + struct hmdfs_time_t time, + unsigned int precision) +{ + struct hmdfs_time_t crtime = { .tv_sec = le64_to_cpu(h->dcache_crtime), + .tv_nsec = le64_to_cpu( + h->dcache_crtime_nsec) }; + struct hmdfs_time_t ctime = { .tv_sec = le64_to_cpu(h->dentry_ctime), + .tv_nsec = le64_to_cpu( + h->dentry_ctime_nsec) }; + struct hmdfs_time_t pre_time = { .tv_sec = precision / MSEC_PER_SEC, + .tv_nsec = precision % MSEC_PER_SEC * + NSEC_PER_MSEC }; if (hmdfs_time_compare(&time, &ctime) != 0) return true; @@ -938,7 +885,7 @@ static bool need_rebuild_dcache(struct hmdfs_dcache_header *h, } static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode, - unsigned long precision) + unsigned long precision) { struct hmdfs_dcache_header header; int overallpage; @@ -946,15 +893,13 @@ static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode, loff_t pos = 0; overallpage = get_dentry_group_cnt(file_inode(filp)); - if (overallpage == 0) - { + if (overallpage == 0) { hmdfs_err("cache file size is 0"); return false; } bytes = kernel_read(filp, &header, sizeof(header), &pos); - if (bytes != sizeof(header)) - { + if (bytes != sizeof(header)) { hmdfs_err("read file failed, err:%zd", bytes); return false; } @@ -963,8 +908,8 @@ static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode, } struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi, - const char *recvpath, - struct path *path) + const char *recvpath, + struct path *path) { struct cache_file_node *cfn = NULL; struct file *file; @@ -974,8 +919,7 @@ struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi, return NULL; if (!hmdfs_server_cache_validate(cfn->filp, path->dentry->d_inode, - sbi->dcache_precision)) - { + sbi->dcache_precision)) { remove_cfn(cfn); release_cfn(cfn); return NULL; @@ -988,8 +932,8 @@ struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi, } bool hmdfs_client_cache_validate(struct hmdfs_sb_info *sbi, - struct readdir_request *readdir_recv, - struct path *path) + struct readdir_request *readdir_recv, + struct path *path) { struct inode *inode = path->dentry->d_inode; struct hmdfs_dcache_header header; @@ -1004,11 +948,11 @@ bool hmdfs_client_cache_validate(struct hmdfs_sb_info *sbi, header.dentry_ctime_nsec = readdir_recv->dentry_ctime_nsec; return !need_rebuild_dcache(&header, inode->i_ctime, - sbi->dcache_precision); + sbi->dcache_precision); } static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, - struct dentry *lo_d) + struct dentry *lo_d) { struct hmdfs_dentry_info *di = hmdfs_d(peer->sbi->sb->s_root); struct dentry *lo_d_root = di->lower_path.dentry; @@ -1024,14 +968,12 @@ static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, /* To generate a reversed path str */ for (lo_d_tmp = lo_d; lo_d_tmp != lo_d_root && !IS_ROOT(lo_d_tmp); - lo_d_tmp = lo_d_tmp->d_parent) - { + lo_d_tmp = lo_d_tmp->d_parent) { u32 dlen = lo_d_tmp->d_name.len; int reverse_index = dlen - 1; /* Considering the appended slash and '\0' */ - if (unlikely(path_len + dlen + 1 > PATH_MAX - 1)) - { + if (unlikely(path_len + dlen + 1 > PATH_MAX - 1)) { kfree(lo_p_buf); return ERR_PTR(-ENAMETOOLONG); } @@ -1043,7 +985,7 @@ static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, /* Reverse the reversed path str to get the real path str */ for (buf_head = lo_p_buf, buf_tail = lo_p_buf + path_len - 1; - buf_head < buf_tail; ++buf_head, --buf_tail) + buf_head < buf_tail; ++buf_head, --buf_tail) swap(*buf_head, *buf_tail); if (path_len == 0) @@ -1052,7 +994,7 @@ static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, } static int server_lookup(struct hmdfs_peer *peer, const char *req_path, - struct path *path) + struct path *path) { struct path root_path; int err = 0; @@ -1062,7 +1004,7 @@ static int server_lookup(struct hmdfs_peer *peer, const char *req_path, goto out_noroot; err = vfs_path_lookup(root_path.dentry, root_path.mnt, req_path, - 0, path); + 0, path); path_put(&root_path); out_noroot: return err; @@ -1077,7 +1019,7 @@ static int server_lookup(struct hmdfs_peer *peer, const char *req_path, * return the lower path's name, with characters' cases matched */ static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path, - struct path *lo_p) + struct path *lo_p) { char *lo_p_name = ERR_PTR(-ENOENT); struct path up_p; @@ -1091,8 +1033,7 @@ static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path, path_put(&up_p); lo_p_name = server_lower_dentry_path_raw(peer, lo_p->dentry); - if (IS_ERR(lo_p_name)) - { + if (IS_ERR(lo_p_name)) { err = PTR_ERR(lo_p_name); path_put(lo_p); } @@ -1101,30 +1042,26 @@ static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path, } void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct open_request *recv = data; - int sizeread = sizeof(struct open_response); + bool is_prefetch = hm_isprefetch(cmd->operations.reserved); + int sizeread = sizeof(struct open_response) - (is_prefetch ? + 0 : HMDFS_PAGE_SIZE + 1); struct open_response *resp = NULL; struct hmdfs_open_info *info = NULL; int ret = 0; - loff_t pos = 0; - - struct path lo_p; - char *lo_p_name = NULL; trace_hmdfs_server_open_enter(con, recv); resp = kzalloc(sizeread, GFP_KERNEL); info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!resp || !info) - { + if (!resp || !info) { ret = -ENOMEM; goto err_free; } - if (path_contain_dotdot(recv->buf, recv->path_len)) - { + if (path_contain_dotdot(recv->buf, recv->path_len)) { ret = -EINVAL; goto err_free; } @@ -1132,8 +1069,7 @@ void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, info->file = hmdfs_open_file(con, recv->buf, recv->file_type, &info->file_id); - if (IS_ERR(info->file)) - { + if (IS_ERR(info->file)) { ret = PTR_ERR(info->file); goto err_free; } @@ -1144,28 +1080,17 @@ void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_update_open_response(con, cmd, info, resp); - ret = kernel_read(info->file, resp->page, HMDFS_PAGE_SIZE, &pos); - if (ret < 0) - { - resp->read_success = 0; - } - else - { - resp->read_success = 1; - if (ret != HMDFS_PAGE_SIZE) - memset(resp->page + ret, 0, HMDFS_PAGE_SIZE - ret); - } - trace_hmdfs_server_open_exit(con, resp, info->file, 0); ret = hmdfs_sendmessage_response(con, cmd, sizeread, resp, 0); - if (ret) - { + if (ret) { hmdfs_err("sending msg response failed, file_id %d, err %d", info->file_id, ret); remove_file_from_conn(con, info->file_id); goto out; } - hmdfs_add_remote_page_cache_list(con, info->file); + + if(is_prefetch) + hmdfs_add_remote_page_cache_list(con, info->file); out: hmdfs_close_path(info->file); @@ -1185,7 +1110,7 @@ void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct readdir_request *readdir_recv = data; struct path lo_p; @@ -1196,33 +1121,28 @@ void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, trace_hmdfs_server_readdir(readdir_recv); - if (path_contain_dotdot(readdir_recv->path, readdir_recv->path_len)) - { + if (path_contain_dotdot(readdir_recv->path, readdir_recv->path_len)) { err = -EINVAL; goto send_err; } lo_p_name = server_lookup_lower(con, readdir_recv->path, &lo_p); - if (IS_ERR(lo_p_name)) - { + if (IS_ERR(lo_p_name)) { err = PTR_ERR(lo_p_name); hmdfs_info("Failed to get lower path: %d", err); goto send_err; } - if (le32_to_cpu(readdir_recv->verify_cache)) - { + if (le32_to_cpu(readdir_recv->verify_cache)) { if (hmdfs_client_cache_validate(con->sbi, readdir_recv, &lo_p)) goto out_response; } filp = hmdfs_server_cache_revalidate(con->sbi, lo_p_name, &lo_p); - if (IS_ERR_OR_NULL(filp)) - { + if (IS_ERR_OR_NULL(filp)) { filp = hmdfs_server_rebuild_dents(con->sbi, &lo_p, &num, - lo_p_name); - if (IS_ERR_OR_NULL(filp)) - { + lo_p_name); + if (IS_ERR_OR_NULL(filp)) { err = PTR_ERR(filp); goto err_lookup_path; } @@ -1245,7 +1165,7 @@ void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct mkdir_request *mkdir_recv = data; @@ -1258,30 +1178,26 @@ void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, int path_len = le32_to_cpu(mkdir_recv->path_len); mkdir_resp = kzalloc(respsize, GFP_KERNEL); - if (!mkdir_resp) - { + if (!mkdir_resp) { err = -ENOMEM; goto mkdir_out; } mkdir_dir = mkdir_recv->path; mkdir_name = mkdir_recv->path + path_len + 1; - if (path_contain_dotdot(mkdir_dir, mkdir_recv->path_len)) - { + if (path_contain_dotdot(mkdir_dir, mkdir_recv->path_len)) { err = -EINVAL; goto mkdir_out; } - if (path_contain_dotdot(mkdir_name, mkdir_recv->name_len)) - { + if (path_contain_dotdot(mkdir_name, mkdir_recv->name_len)) { err = -EINVAL; goto mkdir_out; } dent = hmdfs_root_mkdir(con->device_id, con->sbi->local_dst, - mkdir_dir, mkdir_name, - le16_to_cpu(mkdir_recv->mode)); - if (IS_ERR(dent)) - { + mkdir_dir, mkdir_name, + le16_to_cpu(mkdir_recv->mode)); + if (IS_ERR(dent)) { err = PTR_ERR(dent); hmdfs_err("hmdfs_root_mkdir failed err = %d", err); goto mkdir_out; @@ -1299,7 +1215,7 @@ void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct create_request *create_recv = data; @@ -1312,31 +1228,27 @@ void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, int path_len = le32_to_cpu(create_recv->path_len); create_resp = kzalloc(respsize, GFP_KERNEL); - if (!create_resp) - { + if (!create_resp) { err = -ENOMEM; goto create_out; } create_dir = create_recv->path; create_name = create_recv->path + path_len + 1; - if (path_contain_dotdot(create_dir, create_recv->path_len)) - { + if (path_contain_dotdot(create_dir, create_recv->path_len)) { err = -EINVAL; goto create_out; } - if (path_contain_dotdot(create_name, create_recv->name_len)) - { + if (path_contain_dotdot(create_name, create_recv->name_len)) { err = -EINVAL; goto create_out; } dent = hmdfs_root_create(con->device_id, con->sbi->local_dst, - create_dir, create_name, - le16_to_cpu(create_recv->mode), - create_recv->want_excl); - if (IS_ERR(dent)) - { + create_dir, create_name, + le16_to_cpu(create_recv->mode), + create_recv->want_excl); + if (IS_ERR(dent)) { err = PTR_ERR(dent); hmdfs_err("hmdfs_root_create failed err = %d", err); goto create_out; @@ -1352,7 +1264,7 @@ void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, */ create_resp->i_ino = cpu_to_le64( generate_u64_ino(hmdfs_i(child_inode)->lower_inode->i_ino, - child_inode->i_generation)); + child_inode->i_generation)); dput(dent); create_out: hmdfs_sendmessage_response(con, cmd, respsize, create_resp, err); @@ -1360,7 +1272,7 @@ void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct path root_path; @@ -1370,20 +1282,17 @@ void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, path = rmdir_recv->path; name = rmdir_recv->path + le32_to_cpu(rmdir_recv->path_len) + 1; - if (path_contain_dotdot(path, rmdir_recv->path_len)) - { + if (path_contain_dotdot(path, rmdir_recv->path_len)) { err = -EINVAL; goto rmdir_out; } - if (path_contain_dotdot(name, rmdir_recv->name_len)) - { + if (path_contain_dotdot(name, rmdir_recv->name_len)) { err = -EINVAL; goto rmdir_out; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (!err) - { + if (!err) { err = hmdfs_root_rmdir(con->device_id, &root_path, path, name); path_put(&root_path); } @@ -1393,7 +1302,7 @@ void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct path root_path; @@ -1403,20 +1312,17 @@ void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, path = unlink_recv->path; name = unlink_recv->path + le32_to_cpu(unlink_recv->path_len) + 1; - if (path_contain_dotdot(path, unlink_recv->path_len)) - { + if (path_contain_dotdot(path, unlink_recv->path_len)) { err = -EINVAL; goto unlink_out; } - if (path_contain_dotdot(name, unlink_recv->name_len)) - { + if (path_contain_dotdot(name, unlink_recv->name_len)) { err = -EINVAL; goto unlink_out; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (!err) - { + if (!err) { err = hmdfs_root_unlink(con->device_id, &root_path, path, name); path_put(&root_path); } @@ -1426,7 +1332,7 @@ void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_rename(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; int old_path_len; @@ -1450,37 +1356,33 @@ void hmdfs_server_rename(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, path_new = recv->path + old_path_len + 1; name_old = recv->path + old_path_len + 1 + new_path_len + 1; name_new = recv->path + old_path_len + 1 + new_path_len + 1 + - old_name_len + 1; - if (path_contain_dotdot(path_old, old_path_len)) - { + old_name_len + 1; + if (path_contain_dotdot(path_old, old_path_len)) { err = -EINVAL; goto rename_out; } - if (path_contain_dotdot(path_new, new_path_len)) - { + if (path_contain_dotdot(path_new, new_path_len)) { err = -EINVAL; goto rename_out; } - if (path_contain_dotdot(name_old, old_name_len)) - { + if (path_contain_dotdot(name_old, old_name_len)) { err = -EINVAL; goto rename_out; } - if (path_contain_dotdot(name_new, new_name_len)) - { + if (path_contain_dotdot(name_new, new_name_len)) { err = -EINVAL; goto rename_out; } err = hmdfs_root_rename(con->sbi, con->device_id, path_old, name_old, - path_new, name_new, flags); + path_new, name_new, flags); rename_out: hmdfs_send_err_response(con, cmd, err); } -static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, - ...) +static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, + ... ) { int ret; va_list args; @@ -1488,26 +1390,23 @@ static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, if (!path) return -ENOMEM; - + va_start(args, path_fmt); ret = vsnprintf(path, PATH_MAX, path_fmt, args); va_end(args); - if (ret >= PATH_MAX) - { + if(ret >= PATH_MAX) { ret = -ENAMETOOLONG; goto out; } ret = kern_path(path, LOOKUP_FOLLOW, link_path); - if (ret) - { + if (ret) { hmdfs_err("kern_path failed err = %d", ret); goto out; } - if (!S_ISREG(d_inode(link_path->dentry)->i_mode)) - { + if (!S_ISREG(d_inode(link_path->dentry)->i_mode)) { hmdfs_err("path is dir symlink"); path_put(link_path); ret = -EOPNOTSUPP; @@ -1519,8 +1418,7 @@ static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, return ret; } -struct dir_entry_info -{ +struct dir_entry_info { struct list_head list; char *name; int name_len; @@ -1528,16 +1426,15 @@ struct dir_entry_info }; static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, - int name_len, loff_t offset, u64 ino, - unsigned int d_type) + int name_len, loff_t offset, u64 ino, + unsigned int d_type) { int res = 0; char namestr[NAME_MAX + 1]; struct getdents_callback_real *gc = NULL; struct dentry *child = NULL; - if (name_len > NAME_MAX) - { + if (name_len > NAME_MAX) { hmdfs_err("name_len:%d NAME_MAX:%u", name_len, NAME_MAX); goto out; } @@ -1552,43 +1449,35 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, /* parent lock already hold by iterate_dir */ child = lookup_one_len(name, gc->parent_path->dentry, name_len); - if (IS_ERR(child)) - { + if (IS_ERR(child)) { res = PTR_ERR(child); hmdfs_err("lookup failed because %d", res); goto out; } - if (d_really_is_negative(child)) - { + if (d_really_is_negative(child)) { dput(child); hmdfs_err("lookup failed because negative dentry"); /* just do not fill this entry and continue for next entry */ goto out; } - if (d_type == DT_REG || d_type == DT_DIR) - { + if (d_type == DT_REG || d_type == DT_DIR) { // gc->file is dentry_file, the anonymous tmp_file create_dentry(child, d_inode(child), gc->file, gc->sbi); gc->num++; - } - else if (d_type == DT_LNK) - { + } else if (d_type == DT_LNK) { struct path link_path; - res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", - gc->sbi->local_src, gc->dir, - name); - if (!res) - { - create_dentry(child, d_inode(link_path.dentry), - gc->file, gc->sbi); + res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", + gc->sbi->local_src, gc->dir, + name); + if (!res) { + create_dentry(child, d_inode(link_path.dentry), + gc->file, gc->sbi); path_put(&link_path); gc->num++; - } - else if (res == -ENOENT) - { + } else if (res == -ENOENT) { create_dentry(child, d_inode(child), gc->file, gc->sbi); gc->num++; } @@ -1604,7 +1493,7 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, } static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, - struct file *file, struct file *dentry_file) + struct file *file, struct file *dentry_file) { struct inode *inode = NULL; struct hmdfs_time_t cur_time; @@ -1619,8 +1508,8 @@ static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, // Get the dentries of target directory struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, - struct path *path, loff_t *num, - const char *dir) + struct path *path, loff_t *num, + const char *dir) { int err = 0; struct getdents_callback_real gc = { @@ -1636,16 +1525,14 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, // create a anonymous tmp_file in sbi->cache_dir dentry_file = create_local_dentry_file_cache(sbi); - if (IS_ERR(dentry_file)) - { + if (IS_ERR(dentry_file)) { hmdfs_err("file create failed err=%ld", PTR_ERR(dentry_file)); return dentry_file; } // path is the lower path of the target dir file = dentry_open(path, O_RDONLY | O_DIRECTORY, current_cred()); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { err = PTR_ERR(file); hmdfs_err("dentry_open failed"); goto out; @@ -1657,8 +1544,7 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, gc.file = dentry_file; err = iterate_dir(file, &(gc.ctx)); - if (err) - { + if (err) { hmdfs_err("iterate_dir failed"); goto out; } @@ -1673,8 +1559,7 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, if (!IS_ERR_OR_NULL(file)) fput(file); - if (err) - { + if (err) { fput(dentry_file); dentry_file = ERR_PTR(err); } @@ -1684,7 +1569,7 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, } void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct writepage_request *writepage_recv = data; struct hmdfs_server_writeback *hswb = NULL; @@ -1703,8 +1588,7 @@ void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, file_id = le32_to_cpu(writepage_recv->file_id); file_ver = le64_to_cpu(writepage_recv->file_ver); file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); - if (IS_ERR(file)) - { + if (IS_ERR(file)) { hmdfs_info( "file with id %u does not exist, pgindex %llu, devid %llu", file_id, le64_to_cpu(writepage_recv->index), @@ -1719,19 +1603,16 @@ void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, ret = kernel_write(file, writepage_recv->buf, count, &pos); if (ret != count) err = -EIO; - else if (d_info) - { - spin_lock(&d_info->remote_cache_list_lock); + else if (d_info) { + mutex_lock(&d_info->remote_cache_list_lock); list_for_each_entry_safe(item, item_temp, - &(d_info->remote_cache_list_head), list) - { - if (item->con->device_id == con->device_id) - { + &(d_info->remote_cache_list_head), list) { + if (item->con->device_id == con->device_id) { item->drop_flag = 1; break; } } - spin_unlock(&d_info->remote_cache_list_lock); + mutex_unlock(&d_info->remote_cache_list_lock); } hmdfs_close_path(file); @@ -1743,24 +1624,21 @@ void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_server_check_writeback(hswb); } -static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, - const char *path_name, struct path *dst_path) +static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, + const char *path_name, struct path *dst_path) { struct path link_path; int err; - err = hmdfs_lookup_symlink(&link_path, "%s/%s", sbi->local_dst, - path_name); + err = hmdfs_lookup_symlink(&link_path, "%s/%s", sbi->local_dst, + path_name); if (err) return err; - - if (d_inode(link_path.dentry)->i_sb != sbi->sb) - { + + if (d_inode(link_path.dentry)->i_sb != sbi->sb) { path_put(dst_path); *dst_path = link_path; - } - else - { + } else { path_put(&link_path); } @@ -1768,14 +1646,13 @@ static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, } static struct inode *hmdfs_verify_path(struct dentry *dentry, char *recv_buf, - struct super_block *sb) + struct super_block *sb) { struct inode *inode = d_inode(dentry); struct hmdfs_inode_info *info = NULL; /* if we found path from wrong fs */ - if (inode->i_sb != sb) - { + if (inode->i_sb != sb) { hmdfs_err("super block do not match"); return NULL; } @@ -1790,13 +1667,13 @@ static struct inode *hmdfs_verify_path(struct dentry *dentry, char *recv_buf, * possible because dentry cache can contain stale data. */ hmdfs_info("lower inode is NULL, is remote file: %d", - info->conn != NULL); + info->conn != NULL); return NULL; } static int hmdfs_notify_change(struct vfsmount *mnt, struct dentry *dentry, - struct iattr *attr, - struct inode **delegated_inode) + struct iattr *attr, + struct inode **delegated_inode) { #ifdef CONFIG_SDCARD_FS /* sdcard_fs need to call setattr2, notify_change will call setattr */ @@ -1807,7 +1684,7 @@ static int hmdfs_notify_change(struct vfsmount *mnt, struct dentry *dentry, } void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct dentry *dentry = NULL; @@ -1817,35 +1694,31 @@ void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, struct iattr attr; __u32 valid = le32_to_cpu(recv->valid); - if (path_contain_dotdot(recv->buf, recv->path_len)) - { + if (path_contain_dotdot(recv->buf, recv->path_len)) { err = -EINVAL; goto out; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (err) - { + if (err) { hmdfs_err("kern_path failed err = %d", err); goto out; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf, 0, - &dst_path); + &dst_path); if (err) goto out_put_root; inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb); - if (!inode) - { + if (!inode) { err = -ENOENT; goto out_put_dst; } - if (S_ISLNK(inode->i_mode)) - { + if (S_ISLNK(inode->i_mode)) { err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); - if (err == -ENOENT) + if(err == -ENOENT) err = 0; else if (err) goto out_put_dst; @@ -1874,8 +1747,8 @@ void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } static void update_getattr_response(struct hmdfs_peer *con, struct inode *inode, - struct kstat *ks, - struct getattr_response *resp) + struct kstat *ks, + struct getattr_response *resp) { /* if getattr for link, get ino and mode from actual lower inode */ resp->ino = cpu_to_le64( @@ -1902,7 +1775,7 @@ static void update_getattr_response(struct hmdfs_peer *con, struct inode *inode, } void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { int err = 0; struct getattr_request *recv = data; @@ -1914,8 +1787,7 @@ void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, unsigned int recv_flags = le32_to_cpu(recv->lookup_flags); unsigned int lookup_flags = 0; - if (path_contain_dotdot(recv->buf, recv->path_len)) - { + if (path_contain_dotdot(recv->buf, recv->path_len)) { err = -EINVAL; goto err; } @@ -1925,34 +1797,30 @@ void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, goto err; resp = kzalloc(size_read, GFP_KERNEL); - if (!resp) - { + if (!resp) { err = -ENOMEM; goto err; } err = kern_path(con->sbi->local_dst, 0, &root_path); - if (err) - { + if (err) { hmdfs_err("kern_path failed err = %d", err); goto err_free_resp; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf, - lookup_flags, &dst_path); + lookup_flags, &dst_path); if (err) goto out_put_root; inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb); - if (!inode) - { + if (!inode) { err = -ENOENT; goto out_put_dst; } - if (S_ISLNK(inode->i_mode)) - { + if (S_ISLNK(inode->i_mode)) { err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); - if (err && err != -ENOENT) + if(err && err != -ENOENT) goto out_put_dst; } @@ -1985,7 +1853,7 @@ void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } static void init_statfs_response(struct statfs_response *resp, - struct kstatfs *st) + struct kstatfs *st) { resp->f_type = cpu_to_le64(HMDFS_SUPER_MAGIC); resp->f_bsize = cpu_to_le64(st->f_bsize); @@ -2007,7 +1875,7 @@ static void init_statfs_response(struct statfs_response *resp, } void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { struct statfs_request *recv = data; struct statfs_response *resp = NULL; @@ -2015,37 +1883,32 @@ void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, struct kstatfs *st = NULL; int err = 0; - if (path_contain_dotdot(recv->path, recv->path_len)) - { + if (path_contain_dotdot(recv->path, recv->path_len)) { err = -EINVAL; goto out; } st = kzalloc(sizeof(*st), GFP_KERNEL); - if (!st) - { + if (!st) { err = -ENOMEM; goto out; } resp = kmalloc(sizeof(*resp), GFP_KERNEL); - if (!resp) - { + if (!resp) { err = -ENOMEM; goto free_st; } err = kern_path(con->sbi->local_src, 0, &root_path); - if (err) - { + if (err) { hmdfs_info("kern_path failed err = %d", err); goto free_st; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->path, 0, - &path); - if (err) - { + &path); + if (err) { hmdfs_info("recv->path found failed err = %d", err); goto put_root; } @@ -2070,7 +1933,7 @@ void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_syncfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, - void *data) + void *data) { /* * Reserved interface. There is a difference compared with traditional @@ -2085,7 +1948,7 @@ void hmdfs_server_syncfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } void hmdfs_server_getxattr(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct getxattr_request *recv = data; size_t size = le32_to_cpu(recv->size); @@ -2097,35 +1960,30 @@ void hmdfs_server_getxattr(struct hmdfs_peer *con, char *name = recv->buf + recv->path_len + 1; int err = -ENOMEM; - if (path_contain_dotdot(file_path, recv->path_len)) - { + if (path_contain_dotdot(file_path, recv->path_len)) { err = -EINVAL; goto err; } - if (path_contain_dotdot(name, recv->name_len)) - { + if (path_contain_dotdot(name, recv->name_len)) { err = -EINVAL; goto err; } resp = kzalloc(size_read, GFP_KERNEL); - if (!resp) - { + if (!resp) { err = -ENOMEM; goto err; } err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) - { + if (err) { hmdfs_info("kern_path failed err = %d", err); goto err_free_resp; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, - file_path, 0, &path); - if (err) - { + file_path, 0, &path); + if (err) { hmdfs_info("path found failed err = %d", err); goto err_put_root; } @@ -2134,8 +1992,7 @@ void hmdfs_server_getxattr(struct hmdfs_peer *con, err = vfs_getxattr(path.dentry, name, NULL, size); else err = vfs_getxattr(path.dentry, name, resp->value, size); - if (err < 0) - { + if (err < 0) { hmdfs_info("getxattr failed err %d", err); goto err_put_path; } @@ -2158,7 +2015,7 @@ void hmdfs_server_getxattr(struct hmdfs_peer *con, } void hmdfs_server_setxattr(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct setxattr_request *recv = data; size_t size = le32_to_cpu(recv->size); @@ -2171,38 +2028,31 @@ void hmdfs_server_setxattr(struct hmdfs_peer *con, const void *value = name + recv->name_len + 1; int err; - if (path_contain_dotdot(file_path, recv->path_len)) - { + if (path_contain_dotdot(file_path, recv->path_len)) { err = -EINVAL; goto err; } - if (path_contain_dotdot(name, recv->name_len)) - { + if (path_contain_dotdot(name, recv->name_len)) { err = -EINVAL; goto err; } err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) - { + if (err) { hmdfs_info("kern_path failed err = %d", err); goto err; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, - file_path, 0, &path); - if (err) - { + file_path, 0, &path); + if (err) { hmdfs_info("path found failed err = %d", err); goto err_put_root; } - if (del) - { + if (del) { WARN_ON(flags != XATTR_REPLACE); err = vfs_removexattr(path.dentry, name); - } - else - { + } else { err = vfs_setxattr(path.dentry, name, value, size, flags); } @@ -2214,7 +2064,7 @@ void hmdfs_server_setxattr(struct hmdfs_peer *con, } void hmdfs_server_listxattr(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct listxattr_request *recv = data; size_t size = le32_to_cpu(recv->size); @@ -2225,29 +2075,25 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, struct path path; int err = 0; - if (path_contain_dotdot(file_path, recv->path_len)) - { + if (path_contain_dotdot(file_path, recv->path_len)) { err = -EINVAL; goto err; } resp = kzalloc(size_read, GFP_KERNEL); - if (!resp) - { + if (!resp) { err = -ENOMEM; goto err; } err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); - if (err) - { + if (err) { hmdfs_info("kern_path failed err = %d", err); goto err_free_resp; } err = vfs_path_lookup(root_path.dentry, root_path.mnt, - file_path, 0, &path); - if (err) - { + file_path, 0, &path); + if (err) { hmdfs_info("path found failed err = %d", err); goto err_put_root; } @@ -2256,8 +2102,7 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, err = vfs_listxattr(path.dentry, NULL, size); else err = vfs_listxattr(path.dentry, resp->list, size); - if (err < 0) - { + if (err < 0) { hmdfs_info("listxattr failed err = %d", err); goto err_put_path; } @@ -2280,22 +2125,20 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, } void hmdfs_server_get_drop_push(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data) + struct hmdfs_head_cmd *cmd, void *data) { struct drop_push_request *dp_recv = data; struct path root_path, path; int err; char *tmp_path = NULL; - if (path_contain_dotdot(dp_recv->path, dp_recv->path_len)) - { + if (path_contain_dotdot(dp_recv->path, dp_recv->path_len)) { err = -EINVAL; goto quickack; } err = kern_path(con->sbi->real_dst, 0, &root_path); - if (err) - { + if (err) { hmdfs_err("kern_path failed err = %d", err); goto quickack; } @@ -2303,12 +2146,11 @@ void hmdfs_server_get_drop_push(struct hmdfs_peer *con, if (!tmp_path) goto out; snprintf(tmp_path, PATH_MAX, "/" DEVICE_VIEW_ROOT "/%s%s", - con->cid, dp_recv->path); + con->cid, dp_recv->path); err = vfs_path_lookup(root_path.dentry, root_path.mnt, tmp_path, 0, - &path); - if (err) - { + &path); + if (err) { hmdfs_info("path found failed err = %d", err); goto free; } @@ -2351,15 +2193,13 @@ void hmdfs_server_get_drop_page_push(struct hmdfs_peer *con, // Learn from hmdfs_server_get_drop_push const char *root_name = con->sbi->real_dst; - if (path_contain_dotdot(dpp_recv.buf, dpp_recv.path_len)) - { + if (path_contain_dotdot(dpp_recv.buf, dpp_recv.path_len)) { err = -EINVAL; goto quickack; } err = kern_path(root_name, 0, &root_path); - if (err) - { + if (err) { hmdfs_err("kern_path failed at %s, err = %d", root_name, err); goto quickack; } @@ -2372,8 +2212,7 @@ void hmdfs_server_get_drop_page_push(struct hmdfs_peer *con, err = vfs_path_lookup(root_path.dentry, root_path.mnt, tmp_path, 0, &path); - if (err) - { + if (err) { hmdfs_info("path found failed at %s, err = %d", dpp_recv.buf, err); goto out_tfree; } @@ -2409,4 +2248,4 @@ void hmdfs_server_get_drop_page_push(struct hmdfs_peer *con, quickack: set_conn_sock_quickack(con); -} +} \ No newline at end of file diff --git a/fs/hmdfs/hmdfs_server.h b/fs/hmdfs/hmdfs_server.h index cab043009c80..0ca5f883abb5 100644 --- a/fs/hmdfs/hmdfs_server.h +++ b/fs/hmdfs/hmdfs_server.h @@ -20,8 +20,7 @@ #define DATA_SEC_LEVEL_LABEL "user.security" #define DATA_SEC_LEVEL_LENGTH 10 -struct drop_page_push_recv -{ +struct drop_page_push_recv { __u64 file_size; struct hmdfs_time_t remote_ctime; struct hmdfs_time_t stable_ctime; @@ -84,7 +83,7 @@ void hmdfs_server_listxattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, void hmdfs_server_get_drop_push(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, void *data); void hmdfs_server_get_drop_page_push(struct hmdfs_peer *con, - struct hmdfs_head_cmd *cmd, void *data); + struct hmdfs_head_cmd *cmd, void *data); void __init hmdfs_server_add_node_evt_cb(void); #endif diff --git a/fs/hmdfs/inode_local.c b/fs/hmdfs/inode_local.c index 617d73eb696e..087d179bec2e 100644 --- a/fs/hmdfs/inode_local.c +++ b/fs/hmdfs/inode_local.c @@ -41,7 +41,7 @@ int init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry, INIT_LIST_HEAD(&info->cache_list_head); INIT_LIST_HEAD(&info->remote_cache_list_head); spin_lock_init(&info->cache_list_lock); - spin_lock_init(&info->remote_cache_list_lock); + mutex_init(&info->remote_cache_list_lock); mutex_init(&info->cache_pull_lock); spin_lock_init(&info->lock); info->dentry_type = dentry_type; -- Gitee