On Wed 24-09-25 14:05:49, Jeff Layton wrote:
> In order to add directory delegation support, we need to break
> delegations on the parent whenever there is going to be a change in the
> directory.
> 
> vfs_link, vfs_unlink, and vfs_rename all have existing delegation break
> handling for the children in the rename. Add the necessary calls for
> breaking delegations in the parent(s) as well.
> 
> Signed-off-by: Jeff Layton <[email protected]>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <[email protected]>

                                                                Honza

> ---
>  fs/namei.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index 
> cd43ff89fbaa38206db2aec4f097ca119819f92e..cd517eb232317d326e6d2fc5a60cb4c7569a137d
>  100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -4580,6 +4580,9 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode 
> *dir,
>       else {
>               error = security_inode_unlink(dir, dentry);
>               if (!error) {
> +                     error = try_break_deleg(dir, delegated_inode);
> +                     if (error)
> +                             goto out;
>                       error = try_break_deleg(target, delegated_inode);
>                       if (error)
>                               goto out;
> @@ -4849,7 +4852,9 @@ int vfs_link(struct dentry *old_dentry, struct 
> mnt_idmap *idmap,
>       else if (max_links && inode->i_nlink >= max_links)
>               error = -EMLINK;
>       else {
> -             error = try_break_deleg(inode, delegated_inode);
> +             error = try_break_deleg(dir, delegated_inode);
> +             if (!error)
> +                     error = try_break_deleg(inode, delegated_inode);
>               if (!error)
>                       error = dir->i_op->link(old_dentry, dir, new_dentry);
>       }
> @@ -5116,6 +5121,14 @@ int vfs_rename(struct renamedata *rd)
>                   old_dir->i_nlink >= max_links)
>                       goto out;
>       }
> +     error = try_break_deleg(old_dir, delegated_inode);
> +     if (error)
> +             goto out;
> +     if (new_dir != old_dir) {
> +             error = try_break_deleg(new_dir, delegated_inode);
> +             if (error)
> +                     goto out;
> +     }
>       if (!is_dir) {
>               error = try_break_deleg(source, delegated_inode);
>               if (error)
> 
> -- 
> 2.51.0
> 
-- 
Jan Kara <[email protected]>
SUSE Labs, CR

Reply via email to