From 60ad96c6da91b49c3c8cd66e9eadcfc2db741a0f Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Thu, 1 Jun 2023 15:55:49 +0800 Subject: [PATCH 1/2] hmdfs: rename across devices return errno EXDEV Signed-off-by: Qiheng Lin Change-Id: I7011e7839c829a084e34dc3de1fac25d15d70548 --- fs/hmdfs/inode_cloud_merge.c | 5 +++++ fs/hmdfs/inode_local.c | 4 ++++ fs/hmdfs/inode_remote.c | 2 ++ 3 files changed, 11 insertions(+) diff --git a/fs/hmdfs/inode_cloud_merge.c b/fs/hmdfs/inode_cloud_merge.c index d8cbebe7f972..1d1dc7ee39f5 100644 --- a/fs/hmdfs/inode_cloud_merge.c +++ b/fs/hmdfs/inode_cloud_merge.c @@ -650,6 +650,11 @@ static int hmdfs_rename_cloud_merge(struct inode *old_dir, ret = -EACCES; goto rename_out; } + if (hmdfs_d(old_dentry)->device_id != hmdfs_d(new_dentry)->device_id) { + ret = -EXDEV; + goto rename_out; + } + rec_op_para = kmalloc(sizeof(*rec_op_para), GFP_KERNEL); if (!rec_op_para) { ret = -ENOMEM; diff --git a/fs/hmdfs/inode_local.c b/fs/hmdfs/inode_local.c index a06e5066ed06..346309fd94aa 100644 --- a/fs/hmdfs/inode_local.c +++ b/fs/hmdfs/inode_local.c @@ -672,6 +672,10 @@ int hmdfs_rename_local(struct inode *old_dir, struct dentry *old_dentry, err = -EACCES; goto rename_out; } + if (hmdfs_d(old_dentry)->device_id != hmdfs_d(new_dentry)->device_id) { + err = -EXDEV; + goto rename_out; + } if (S_ISREG(old_dentry->d_inode->i_mode)) { err = hmdfs_rename_local_dentry(old_dir, old_dentry, new_dir, diff --git a/fs/hmdfs/inode_remote.c b/fs/hmdfs/inode_remote.c index 6a19e6e6b135..f906b2410407 100644 --- a/fs/hmdfs/inode_remote.c +++ b/fs/hmdfs/inode_remote.c @@ -809,6 +809,8 @@ int hmdfs_rename_remote(struct inode *old_dir, struct dentry *old_dentry, hmdfs_file_type(new_dentry->d_name.name) != HMDFS_TYPE_COMMON) { return -EACCES; } + if (hmdfs_d(old_dentry)->device_id != hmdfs_d(new_dentry)->device_id) + return -EXDEV; relative_old_dir_path = hmdfs_get_dentry_relative_path(old_dentry->d_parent); -- Gitee From ffb9b5e4c0e4c77424e8b04dea0dc57ee1f4000a Mon Sep 17 00:00:00 2001 From: linqiheng Date: Thu, 1 Jun 2023 15:55:49 +0800 Subject: [PATCH 2/2] hmdfs: fix drop_nlink warns when continuous unlink Signed-off-by: linqiheng --- fs/hmdfs/inode_merge.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index c1014e0f552e..0ef8defc2b86 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -1173,6 +1173,7 @@ int do_unlink_merge(struct inode *dir, struct dentry *dentry) struct hmdfs_dentry_comrade *comrade = NULL; struct dentry *lo_d = NULL; struct dentry *lo_d_dir = NULL; + struct dentry *lo_d_lookup = NULL; struct inode *lo_i_dir = NULL; wait_event(dim->wait_queue, !has_merge_lookup_work(dim)); @@ -1182,8 +1183,19 @@ int do_unlink_merge(struct inode *dir, struct dentry *dentry) lo_d = comrade->lo_d; dget(lo_d); lo_d_dir = lock_parent(lo_d); + /* lo_d could be unhashed, need to lookup again here */ + lo_d_lookup = lookup_one_len(lo_d->d_name.name, lo_d_dir, + strlen(lo_d->d_name.name)); + if (IS_ERR(lo_d_lookup)) { + ret = PTR_ERR(lo_d_lookup); + hmdfs_err("lookup_one_len failed, err = %d", ret); + unlock_dir(lo_d_dir); + dput(lo_d); + break; + } lo_i_dir = d_inode(lo_d_dir); - ret = vfs_unlink(lo_i_dir, lo_d, NULL); // lo_d GET + ret = vfs_unlink(lo_i_dir, lo_d_lookup, NULL); + dput(lo_d_lookup); unlock_dir(lo_d_dir); dput(lo_d); if (ret) -- Gitee