Message ID | 20231122193652.419091-3-viro@zeniv.linux.org.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/9] reiserfs: Avoid touching renamed directory if parent does not change | expand |
On Wed 22-11-23 19:36:46, Al Viro wrote: > We can't really afford locking the source on same-directory rename; > currently vfs_rename() tries to do that, but it will have to be > changed. The logics in udf_rename() is lazy and goes looking for > ".." in source even in same-directory case. It's not hard to get > rid of that, leaving that behaviour only for cross-directory case; > that VFS can get locks safely (and will keep doing that after the > coming changes). > > Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Looks good. Feel free to add: Reviewed-by: Jan Kara <jack@suse.cz> Honza > --- > fs/udf/namei.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/fs/udf/namei.c b/fs/udf/namei.c > index 3508ac484da3..fac806a7a8d4 100644 > --- a/fs/udf/namei.c > +++ b/fs/udf/namei.c > @@ -766,7 +766,7 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, > struct inode *old_inode = d_inode(old_dentry); > struct inode *new_inode = d_inode(new_dentry); > struct udf_fileident_iter oiter, niter, diriter; > - bool has_diriter = false; > + bool has_diriter = false, is_dir = false; > int retval; > struct kernel_lb_addr tloc; > > @@ -789,6 +789,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, > if (!empty_dir(new_inode)) > goto out_oiter; > } > + is_dir = true; > + } > + if (is_dir && old_dir != new_dir) { > retval = udf_fiiter_find_entry(old_inode, &dotdot_name, > &diriter); > if (retval == -ENOENT) { > @@ -878,7 +881,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, > udf_dir_entry_len(&diriter.fi)); > udf_fiiter_write_fi(&diriter, NULL); > udf_fiiter_release(&diriter); > + } > > + if (is_dir) { > inode_dec_link_count(old_dir); > if (new_inode) > inode_dec_link_count(new_inode); > -- > 2.39.2 >
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 3508ac484da3..fac806a7a8d4 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -766,7 +766,7 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct inode *old_inode = d_inode(old_dentry); struct inode *new_inode = d_inode(new_dentry); struct udf_fileident_iter oiter, niter, diriter; - bool has_diriter = false; + bool has_diriter = false, is_dir = false; int retval; struct kernel_lb_addr tloc; @@ -789,6 +789,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, if (!empty_dir(new_inode)) goto out_oiter; } + is_dir = true; + } + if (is_dir && old_dir != new_dir) { retval = udf_fiiter_find_entry(old_inode, &dotdot_name, &diriter); if (retval == -ENOENT) { @@ -878,7 +881,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, udf_dir_entry_len(&diriter.fi)); udf_fiiter_write_fi(&diriter, NULL); udf_fiiter_release(&diriter); + } + if (is_dir) { inode_dec_link_count(old_dir); if (new_inode) inode_dec_link_count(new_inode);
We can't really afford locking the source on same-directory rename; currently vfs_rename() tries to do that, but it will have to be changed. The logics in udf_rename() is lazy and goes looking for ".." in source even in same-directory case. It's not hard to get rid of that, leaving that behaviour only for cross-directory case; that VFS can get locks safely (and will keep doing that after the coming changes). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- fs/udf/namei.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)