Re: [PATCH v5 01/30] orangefs: rework posix acl handling when creating new filesystem objects

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello... I have applied your v5 patch series to 6.1-rc2. I get
numerous acl related xfstests failures with your patch.

generic/105 is the first one that fails, so I got started dee-ciphering
what it does.

I hoped I could find what it is in the patch that causes the
regression, but I have not yet, and we're already up to rc4.

I have a sequence of events that is part of generic/105 where
I believe "the bad thing" happens, I thought I'd show you, you
might know right away what is wrong...

6.1-rc2 without the patch series:
root@vm1 ~]# cd /scratch
[root@vm1 scratch]# mkdir -m 600 subdir
[root@vm1 scratch]# chown 13 subdir
[root@vm1 scratch]# echo data > subdir/file
[root@vm1 scratch]# ls -l subdir/file | awk '{ print $1, $3 }'
-rw-r--r--. root

6.1-rc2 with the patch series:
[root@vm1 hubcap]# cd /scratch
[root@vm1 scratch]#  mkdir -m 600 subdir
[root@vm1 scratch]# chown 13 subdir
[root@vm1 scratch]# echo data > subdir/file
[root@vm1 scratch]# ls -l subdir/file | awk '{ print $1, $3 }'
-rw-rw-rw-. root

The commit message for the orangefs part of the patch
says "calculate the correct mode directly before
actually creating the inode."

Anywho... I'll keep looking...

-Mike



On Tue, Oct 18, 2022 at 7:57 AM Christian Brauner <brauner@xxxxxxxxxx> wrote:
>
> When creating new filesytem objects orangefs used to create posix acls
> after it had created and inserted a new inode. This made it necessary to
> all posix_acl_chmod() on the newly created inode in case the mode of the
> inode would be changed by the posix acls.
>
> Instead of doing it this way calculate the correct mode directly before
> actually creating the inode. So we first create posix acls, then pass
> the mode that posix acls mandate into the orangefs getattr helper and
> calculate the correct mode. This is needed so we can simply change
> posix_acl_chmod() to take a dentry instead of an inode argument in the
> next patch.
>
> Reviewed-by: Christoph Hellwig <hch@xxxxxx>
> Signed-off-by: Christian Brauner (Microsoft) <brauner@xxxxxxxxxx>
> ---
>
> Notes:
>     /* v2 */
>     Christoph Hellwig <hch@xxxxxx>:
>     - Add separate patch for orangefs rework.
>
>     /* v3 */
>     unchanged
>
>     /* v4 */
>     Christoph Hellwig <hch@xxxxxx>:
>     - drop extern from function declaration
>
>     /* v5 */
>     unchanged
>
>  fs/orangefs/acl.c             | 44 ++---------------------------------
>  fs/orangefs/inode.c           | 44 ++++++++++++++++++++++++++++-------
>  fs/orangefs/orangefs-kernel.h |  6 +++--
>  fs/orangefs/orangefs-utils.c  | 10 ++++++--
>  4 files changed, 50 insertions(+), 54 deletions(-)
>
> diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c
> index 605e5a3506ec..0e2db840c217 100644
> --- a/fs/orangefs/acl.c
> +++ b/fs/orangefs/acl.c
> @@ -64,8 +64,7 @@ struct posix_acl *orangefs_get_acl(struct inode *inode, int type, bool rcu)
>         return acl;
>  }
>
> -static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
> -                             int type)
> +int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
>  {
>         int error = 0;
>         void *value = NULL;
> @@ -153,46 +152,7 @@ int orangefs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
>         rc = __orangefs_set_acl(inode, acl, type);
>
>         if (!rc && (iattr.ia_valid == ATTR_MODE))
> -               rc = __orangefs_setattr(inode, &iattr);
> +               rc = __orangefs_setattr_mode(inode, &iattr);
>
>         return rc;
>  }
> -
> -int orangefs_init_acl(struct inode *inode, struct inode *dir)
> -{
> -       struct posix_acl *default_acl, *acl;
> -       umode_t mode = inode->i_mode;
> -       struct iattr iattr;
> -       int error = 0;
> -
> -       error = posix_acl_create(dir, &mode, &default_acl, &acl);
> -       if (error)
> -               return error;
> -
> -       if (default_acl) {
> -               error = __orangefs_set_acl(inode, default_acl,
> -                                          ACL_TYPE_DEFAULT);
> -               posix_acl_release(default_acl);
> -       } else {
> -               inode->i_default_acl = NULL;
> -       }
> -
> -       if (acl) {
> -               if (!error)
> -                       error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
> -               posix_acl_release(acl);
> -       } else {
> -               inode->i_acl = NULL;
> -       }
> -
> -       /* If mode of the inode was changed, then do a forcible ->setattr */
> -       if (mode != inode->i_mode) {
> -               memset(&iattr, 0, sizeof iattr);
> -               inode->i_mode = mode;
> -               iattr.ia_mode = mode;
> -               iattr.ia_valid |= ATTR_MODE;
> -               __orangefs_setattr(inode, &iattr);
> -       }
> -
> -       return error;
> -}
> diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
> index 7a8c0c6e698d..35788cde6d24 100644
> --- a/fs/orangefs/inode.c
> +++ b/fs/orangefs/inode.c
> @@ -828,15 +828,22 @@ int __orangefs_setattr(struct inode *inode, struct iattr *iattr)
>         spin_unlock(&inode->i_lock);
>         mark_inode_dirty(inode);
>
> -       if (iattr->ia_valid & ATTR_MODE)
> -               /* change mod on a file that has ACLs */
> -               ret = posix_acl_chmod(&init_user_ns, inode, inode->i_mode);
> -
>         ret = 0;
>  out:
>         return ret;
>  }
>
> +int __orangefs_setattr_mode(struct inode *inode, struct iattr *iattr)
> +{
> +       int ret;
> +
> +       ret = __orangefs_setattr(inode, iattr);
> +       /* change mode on a file that has ACLs */
> +       if (!ret && (iattr->ia_valid & ATTR_MODE))
> +               ret = posix_acl_chmod(&init_user_ns, inode, inode->i_mode);
> +       return ret;
> +}
> +
>  /*
>   * Change attributes of an object referenced by dentry.
>   */
> @@ -849,7 +856,7 @@ int orangefs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
>         ret = setattr_prepare(&init_user_ns, dentry, iattr);
>         if (ret)
>                 goto out;
> -       ret = __orangefs_setattr(d_inode(dentry), iattr);
> +       ret = __orangefs_setattr_mode(d_inode(dentry), iattr);
>         sync_inode_metadata(d_inode(dentry), 1);
>  out:
>         gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n",
> @@ -1097,8 +1104,9 @@ struct inode *orangefs_iget(struct super_block *sb,
>   * Allocate an inode for a newly created file and insert it into the inode hash.
>   */
>  struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
> -               int mode, dev_t dev, struct orangefs_object_kref *ref)
> +               umode_t mode, dev_t dev, struct orangefs_object_kref *ref)
>  {
> +       struct posix_acl *acl = NULL, *default_acl = NULL;
>         unsigned long hash = orangefs_handle_hash(ref);
>         struct inode *inode;
>         int error;
> @@ -1115,16 +1123,33 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
>         if (!inode)
>                 return ERR_PTR(-ENOMEM);
>
> +       error = posix_acl_create(dir, &mode, &default_acl, &acl);
> +       if (error)
> +               goto out_iput;
> +
>         orangefs_set_inode(inode, ref);
>         inode->i_ino = hash;    /* needed for stat etc */
>
> -       error = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_NEW);
> +       error = __orangefs_inode_getattr(inode, mode, ORANGEFS_GETATTR_NEW);
>         if (error)
>                 goto out_iput;
>
>         orangefs_init_iops(inode);
>         inode->i_rdev = dev;
>
> +       if (default_acl) {
> +               error = __orangefs_set_acl(inode, default_acl,
> +                                          ACL_TYPE_DEFAULT);
> +               if (error)
> +                       goto out_iput;
> +       }
> +
> +       if (acl) {
> +               error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
> +               if (error)
> +                       goto out_iput;
> +       }
> +
>         error = insert_inode_locked4(inode, hash, orangefs_test_inode, ref);
>         if (error < 0)
>                 goto out_iput;
> @@ -1132,10 +1157,13 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
>         gossip_debug(GOSSIP_INODE_DEBUG,
>                      "Initializing ACL's for inode %pU\n",
>                      get_khandle_from_ino(inode));
> -       orangefs_init_acl(inode, dir);
> +       posix_acl_release(acl);
> +       posix_acl_release(default_acl);
>         return inode;
>
>  out_iput:
>         iput(inode);
> +       posix_acl_release(acl);
> +       posix_acl_release(default_acl);
>         return ERR_PTR(error);
>  }
> diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h
> index b5940ec1836a..3298b15684b7 100644
> --- a/fs/orangefs/orangefs-kernel.h
> +++ b/fs/orangefs/orangefs-kernel.h
> @@ -103,13 +103,13 @@ enum orangefs_vfs_op_states {
>  #define ORANGEFS_CACHE_CREATE_FLAGS 0
>  #endif
>
> -extern int orangefs_init_acl(struct inode *inode, struct inode *dir);
>  extern const struct xattr_handler *orangefs_xattr_handlers[];
>
>  extern struct posix_acl *orangefs_get_acl(struct inode *inode, int type, bool rcu);
>  extern int orangefs_set_acl(struct user_namespace *mnt_userns,
>                             struct inode *inode, struct posix_acl *acl,
>                             int type);
> +int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
>
>  /*
>   * orangefs data structures
> @@ -356,11 +356,12 @@ void fsid_key_table_finalize(void);
>  vm_fault_t orangefs_page_mkwrite(struct vm_fault *);
>  struct inode *orangefs_new_inode(struct super_block *sb,
>                               struct inode *dir,
> -                             int mode,
> +                             umode_t mode,
>                               dev_t dev,
>                               struct orangefs_object_kref *ref);
>
>  int __orangefs_setattr(struct inode *, struct iattr *);
> +int __orangefs_setattr_mode(struct inode *inode, struct iattr *iattr);
>  int orangefs_setattr(struct user_namespace *, struct dentry *, struct iattr *);
>
>  int orangefs_getattr(struct user_namespace *mnt_userns, const struct path *path,
> @@ -422,6 +423,7 @@ int orangefs_inode_setxattr(struct inode *inode,
>  #define ORANGEFS_GETATTR_SIZE 2
>
>  int orangefs_inode_getattr(struct inode *, int);
> +int __orangefs_inode_getattr(struct inode *inode, umode_t mode, int flags);
>
>  int orangefs_inode_check_changed(struct inode *inode);
>
> diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c
> index 46b7dcff18ac..334a2fd98c37 100644
> --- a/fs/orangefs/orangefs-utils.c
> +++ b/fs/orangefs/orangefs-utils.c
> @@ -233,7 +233,7 @@ static int orangefs_inode_is_stale(struct inode *inode,
>         return 0;
>  }
>
> -int orangefs_inode_getattr(struct inode *inode, int flags)
> +int __orangefs_inode_getattr(struct inode *inode, umode_t mode, int flags)
>  {
>         struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
>         struct orangefs_kernel_op_s *new_op;
> @@ -369,7 +369,8 @@ int orangefs_inode_getattr(struct inode *inode, int flags)
>
>         /* special case: mark the root inode as sticky */
>         inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
> -           orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
> +           orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes) |
> +           mode;
>
>         orangefs_inode->getattr_time = jiffies +
>             orangefs_getattr_timeout_msecs*HZ/1000;
> @@ -381,6 +382,11 @@ int orangefs_inode_getattr(struct inode *inode, int flags)
>         return ret;
>  }
>
> +int orangefs_inode_getattr(struct inode *inode, int flags)
> +{
> +       return __orangefs_inode_getattr(inode, 0, flags);
> +}
> +
>  int orangefs_inode_check_changed(struct inode *inode)
>  {
>         struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
> --
> 2.34.1
>



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux