Skip to content

Commit 138060b

Browse files
committed
fs: pass dentry to set acl method
The current way of setting and getting posix acls through the generic xattr interface is error prone and type unsafe. The vfs needs to interpret and fixup posix acls before storing or reporting it to userspace. Various hacks exist to make this work. The code is hard to understand and difficult to maintain in it's current form. Instead of making this work by hacking posix acls through xattr handlers we are building a dedicated posix acl api around the get and set inode operations. This removes a lot of hackiness and makes the codepaths easier to maintain. A lot of background can be found in [1]. Since some filesystem rely on the dentry being available to them when setting posix acls (e.g., 9p and cifs) they cannot rely on set acl inode operation. But since ->set_acl() is required in order to use the generic posix acl xattr handlers filesystems that do not implement this inode operation cannot use the handler and need to implement their own dedicated posix acl handlers. Update the ->set_acl() inode method to take a dentry argument. This allows all filesystems to rely on ->set_acl(). As far as I can tell all codepaths can be switched to rely on the dentry instead of just the inode. Note that the original motivation for passing the dentry separate from the inode instead of just the dentry in the xattr handlers was because of security modules that call security_d_instantiate(). This hook is called during d_instantiate_new(), d_add(), __d_instantiate_anon(), and d_splice_alias() to initialize the inode's security context and possibly to set security.* xattrs. Since this only affects security.* xattrs this is completely irrelevant for posix acls. Link: https://lore.kernel.org/all/[email protected] [1] Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Christian Brauner (Microsoft) <[email protected]>
1 parent 4053d25 commit 138060b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+121
-95
lines changed

Documentation/filesystems/vfs.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ As of kernel 2.6.22, the following members are defined:
443443
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
444444
unsigned open_flag, umode_t create_mode);
445445
int (*tmpfile) (struct user_namespace *, struct inode *, struct file *, umode_t);
446-
int (*set_acl)(struct user_namespace *, struct inode *, struct posix_acl *, int);
446+
int (*set_acl)(struct user_namespace *, struct dentry *, struct posix_acl *, int);
447447
int (*fileattr_set)(struct user_namespace *mnt_userns,
448448
struct dentry *dentry, struct fileattr *fa);
449449
int (*fileattr_get)(struct dentry *dentry, struct fileattr *fa);

fs/bad_inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ static int bad_inode_tmpfile(struct user_namespace *mnt_userns,
154154
}
155155

156156
static int bad_inode_set_acl(struct user_namespace *mnt_userns,
157-
struct inode *inode, struct posix_acl *acl,
157+
struct dentry *dentry, struct posix_acl *acl,
158158
int type)
159159
{
160160
return -EIO;

fs/btrfs/acl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,11 @@ int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode,
110110
return ret;
111111
}
112112

113-
int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
113+
int btrfs_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
114114
struct posix_acl *acl, int type)
115115
{
116116
int ret;
117+
struct inode *inode = d_inode(dentry);
117118
umode_t old_mode = inode->i_mode;
118119

119120
if (type == ACL_TYPE_ACCESS && acl) {

fs/btrfs/ctree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3987,7 +3987,7 @@ static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag)
39873987
/* acl.c */
39883988
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
39893989
struct posix_acl *btrfs_get_acl(struct inode *inode, int type, bool rcu);
3990-
int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
3990+
int btrfs_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
39913991
struct posix_acl *acl, int type);
39923992
int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode,
39933993
struct posix_acl *acl, int type);

fs/btrfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5256,7 +5256,7 @@ static int btrfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentr
52565256
err = btrfs_dirty_inode(inode);
52575257

52585258
if (!err && attr->ia_valid & ATTR_MODE)
5259-
err = posix_acl_chmod(mnt_userns, inode, inode->i_mode);
5259+
err = posix_acl_chmod(mnt_userns, dentry, inode->i_mode);
52605260
}
52615261

52625262
return err;

fs/ceph/acl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,14 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type, bool rcu)
8585
return acl;
8686
}
8787

88-
int ceph_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
88+
int ceph_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
8989
struct posix_acl *acl, int type)
9090
{
9191
int ret = 0, size = 0;
9292
const char *name = NULL;
9393
char *value = NULL;
9494
struct iattr newattrs;
95+
struct inode *inode = d_inode(dentry);
9596
struct timespec64 old_ctime = inode->i_ctime;
9697
umode_t new_mode = inode->i_mode, old_mode = inode->i_mode;
9798

fs/ceph/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2255,7 +2255,7 @@ int ceph_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
22552255
err = __ceph_setattr(inode, attr);
22562256

22572257
if (err >= 0 && (attr->ia_valid & ATTR_MODE))
2258-
err = posix_acl_chmod(&init_user_ns, inode, attr->ia_mode);
2258+
err = posix_acl_chmod(&init_user_ns, dentry, attr->ia_mode);
22592259

22602260
return err;
22612261
}

fs/ceph/super.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,7 @@ void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx);
11171117

11181118
struct posix_acl *ceph_get_acl(struct inode *, int, bool);
11191119
int ceph_set_acl(struct user_namespace *mnt_userns,
1120-
struct inode *inode, struct posix_acl *acl, int type);
1120+
struct dentry *dentry, struct posix_acl *acl, int type);
11211121
int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
11221122
struct ceph_acl_sec_ctx *as_ctx);
11231123
void ceph_init_inode_acls(struct inode *inode,

fs/ext2/acl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,12 @@ __ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
219219
* inode->i_mutex: down
220220
*/
221221
int
222-
ext2_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
222+
ext2_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
223223
struct posix_acl *acl, int type)
224224
{
225225
int error;
226226
int update_mode = 0;
227+
struct inode *inode = d_inode(dentry);
227228
umode_t mode = inode->i_mode;
228229

229230
if (type == ACL_TYPE_ACCESS && acl) {

fs/ext2/acl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static inline int ext2_acl_count(size_t size)
5656

5757
/* acl.c */
5858
extern struct posix_acl *ext2_get_acl(struct inode *inode, int type, bool rcu);
59-
extern int ext2_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
59+
extern int ext2_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
6060
struct posix_acl *acl, int type);
6161
extern int ext2_init_acl (struct inode *, struct inode *);
6262

0 commit comments

Comments
 (0)