Commit 0fac198d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fs.idmapped.overlay.acl.v5.20' of...

Merge tag 'fs.idmapped.overlay.acl.v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux

Pull acl updates from Christian Brauner:
 "Last cycle we introduced support for mounting overlayfs on top of
  idmapped mounts. While looking into additional testing we realized
  that posix acls don't really work correctly with stacking filesystems
  on top of idmapped layers.

  We already knew what the fix were but it would require work that is
  more suitable for the merge window so we turned off posix acls for
  v5.19 for overlayfs on top of idmapped layers with Miklos routing my
  patch upstream in 72a8e05d ("Merge tag 'ovl-fixes-5.19-rc7' [..]").

  This contains the work to support posix acls for overlayfs on top of
  idmapped layers. Since the posix acl fixes should use the new
  vfs{g,u}id_t work the associated branch has been merged in. (We sent a
  pull request for this earlier.)

  We've also pulled in Miklos pull request containing my patch to turn
  of posix acls on top of idmapped layers. This allowed us to avoid
  rebasing the branch which we didn't like because we were already at
  rc7 by then. Merging it in allows this branch to first fix posix acls
  and then to cleanly revert the temporary fix it brought in by commit
  4a47c638 ("ovl: turn of SB_POSIXACL with idmapped layers
  temporarily").

  The last patch in this series adds Seth Forshee as a co-maintainer for
  idmapped mounts. Seth has been integral to all of this work and is
  also the main architect behind the filesystem idmapping work which
  ultimately made filesystems such as FUSE and overlayfs available in
  containers. He continues to be active in both development and review.
  I'm very happy he decided to help and he has my full trust. This
  increases the bus factor which is always great for work like this. I'm
  honestly very excited about this because I think in general we don't
  do great in the bringing on new maintainers department"

For more explanations of the ACL issues, see

  https://lore.kernel.org/all/20220801145520.1532837-1-brauner@kernel.org/

* tag 'fs.idmapped.overlay.acl.v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
  Add Seth Forshee as co-maintainer for idmapped mounts
  Revert "ovl: turn of SB_POSIXACL with idmapped layers temporarily"
  ovl: handle idmappings in ovl_get_acl()
  acl: make posix_acl_clone() available to overlayfs
  acl: port to vfs{g,u}id_t
  acl: move idmapped mount fixup into vfs_{g,s}etxattr()
  mnt_idmapping: add vfs[g,u]id_into_k[g,u]id()
parents bdfae5ce ba40a57f
......@@ -466,10 +466,6 @@ overlay filesystem and the value of st_ino for filesystem objects may not be
persistent and could change even while the overlay filesystem is mounted, as
summarized in the `Inode properties`_ table above.
4) "idmapped mounts"
When the upper or lower layers are idmapped mounts overlayfs will be mounted
without support for POSIX Access Control Lists (ACLs). This limitation will
eventually be lifted.
Changes to underlying filesystems
---------------------------------
......
......@@ -9620,6 +9620,7 @@ F: drivers/input/misc/ideapad_slidebar.c
IDMAPPED MOUNTS
M: Christian Brauner <brauner@kernel.org>
M: Seth Forshee <sforshee@kernel.org>
L: linux-fsdevel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git
......
......@@ -963,7 +963,7 @@ ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns,
*/
int ksmbd_vfs_setxattr(struct user_namespace *user_ns,
struct dentry *dentry, const char *attr_name,
const void *attr_value, size_t attr_size, int flags)
void *attr_value, size_t attr_size, int flags)
{
int err;
......
......@@ -109,7 +109,7 @@ ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns,
int attr_name_len);
int ksmbd_vfs_setxattr(struct user_namespace *user_ns,
struct dentry *dentry, const char *attr_name,
const void *attr_value, size_t attr_size, int flags);
void *attr_value, size_t attr_size, int flags);
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
size_t *xattr_stream_name_size, int s_type);
int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
......
......@@ -454,23 +454,94 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
return res;
}
/*
* Apply the idmapping of the layer to POSIX ACLs. The caller must pass a clone
* of the POSIX ACLs retrieved from the lower layer to this function to not
* alter the POSIX ACLs for the underlying filesystem.
*/
static void ovl_idmap_posix_acl(struct user_namespace *mnt_userns,
struct posix_acl *acl)
{
for (unsigned int i = 0; i < acl->a_count; i++) {
vfsuid_t vfsuid;
vfsgid_t vfsgid;
struct posix_acl_entry *e = &acl->a_entries[i];
switch (e->e_tag) {
case ACL_USER:
vfsuid = make_vfsuid(mnt_userns, &init_user_ns, e->e_uid);
e->e_uid = vfsuid_into_kuid(vfsuid);
break;
case ACL_GROUP:
vfsgid = make_vfsgid(mnt_userns, &init_user_ns, e->e_gid);
e->e_gid = vfsgid_into_kgid(vfsgid);
break;
}
}
}
/*
* When the relevant layer is an idmapped mount we need to take the idmapping
* of the layer into account and translate any ACL_{GROUP,USER} values
* according to the idmapped mount.
*
* We cannot alter the ACLs returned from the relevant layer as that would
* alter the cached values filesystem wide for the lower filesystem. Instead we
* can clone the ACLs and then apply the relevant idmapping of the layer.
*
* This is obviously only relevant when idmapped layers are used.
*/
struct posix_acl *ovl_get_acl(struct inode *inode, int type, bool rcu)
{
struct inode *realinode = ovl_inode_real(inode);
const struct cred *old_cred;
struct posix_acl *acl;
struct posix_acl *acl, *clone;
struct path realpath;
if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode))
return NULL;
if (rcu)
return get_cached_acl_rcu(realinode, type);
/* Careful in RCU walk mode */
ovl_i_path_real(inode, &realpath);
if (!realpath.dentry) {
WARN_ON(!rcu);
return ERR_PTR(-ECHILD);
}
old_cred = ovl_override_creds(inode->i_sb);
acl = get_acl(realinode, type);
revert_creds(old_cred);
if (rcu) {
acl = get_cached_acl_rcu(realinode, type);
} else {
const struct cred *old_cred;
old_cred = ovl_override_creds(inode->i_sb);
acl = get_acl(realinode, type);
revert_creds(old_cred);
}
/*
* If there are no POSIX ACLs, or we encountered an error,
* or the layer isn't idmapped we don't need to do anything.
*/
if (!is_idmapped_mnt(realpath.mnt) || IS_ERR_OR_NULL(acl))
return acl;
return acl;
/*
* We only get here if the layer is idmapped. So drop out of RCU path
* walk so we can clone the ACLs. There's no need to release the ACLs
* since get_cached_acl_rcu() doesn't take a reference on the ACLs.
*/
if (rcu)
return ERR_PTR(-ECHILD);
clone = posix_acl_clone(acl, GFP_KERNEL);
if (!clone)
clone = ERR_PTR(-ENOMEM);
else
ovl_idmap_posix_acl(mnt_user_ns(realpath.mnt), clone);
/*
* Since we're not in RCU path walk we always need to release the
* original ACLs.
*/
posix_acl_release(acl);
return clone;
}
int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags)
......
......@@ -249,7 +249,8 @@ static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
const char *name, const void *value,
size_t size, int flags)
{
int err = vfs_setxattr(ovl_upper_mnt_userns(ofs), dentry, name, value, size, flags);
int err = vfs_setxattr(ovl_upper_mnt_userns(ofs), dentry, name,
(void *)value, size, flags);
pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n",
dentry, name, min((int)size, 48), value, size, flags, err);
......
......@@ -1003,9 +1003,6 @@ ovl_posix_acl_xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, void *buffer, size_t size)
{
if (!IS_POSIXACL(inode))
return -EOPNOTSUPP;
return ovl_xattr_get(dentry, inode, handler->name, buffer, size);
}
......@@ -1021,9 +1018,6 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
struct posix_acl *acl = NULL;
int err;
if (!IS_POSIXACL(inode))
return -EOPNOTSUPP;
/* Check that everything is OK before copy-up */
if (value) {
acl = posix_acl_from_xattr(&init_user_ns, value, size);
......@@ -1966,20 +1960,6 @@ static struct dentry *ovl_get_root(struct super_block *sb,
return root;
}
static bool ovl_has_idmapped_layers(struct ovl_fs *ofs)
{
unsigned int i;
const struct vfsmount *mnt;
for (i = 0; i < ofs->numlayer; i++) {
mnt = ofs->layers[i].mnt;
if (mnt && is_idmapped_mnt(mnt))
return true;
}
return false;
}
static int ovl_fill_super(struct super_block *sb, void *data, int silent)
{
struct path upperpath = { };
......@@ -2149,10 +2129,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers :
ovl_trusted_xattr_handlers;
sb->s_fs_info = ofs;
if (ovl_has_idmapped_layers(ofs))
pr_warn("POSIX ACLs are not yet supported with idmapped layers, mounting without ACL support.\n");
else
sb->s_flags |= SB_POSIXACL;
sb->s_flags |= SB_POSIXACL;
sb->s_iflags |= SB_I_SKIP_SYNC;
err = -ENOMEM;
......
......@@ -199,7 +199,7 @@ EXPORT_SYMBOL(posix_acl_alloc);
/*
* Clone an ACL.
*/
static struct posix_acl *
struct posix_acl *
posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
{
struct posix_acl *clone = NULL;
......@@ -213,6 +213,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
}
return clone;
}
EXPORT_SYMBOL_GPL(posix_acl_clone);
/*
* Check if an acl is valid. Returns 0 if it is, or -E... otherwise.
......@@ -361,8 +362,8 @@ posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode,
{
const struct posix_acl_entry *pa, *pe, *mask_obj;
int found = 0;
kuid_t uid;
kgid_t gid;
vfsuid_t vfsuid;
vfsgid_t vfsgid;
want &= MAY_READ | MAY_WRITE | MAY_EXEC;
......@@ -370,30 +371,28 @@ posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode,
switch(pa->e_tag) {
case ACL_USER_OBJ:
/* (May have been checked already) */
uid = i_uid_into_mnt(mnt_userns, inode);
if (uid_eq(uid, current_fsuid()))
vfsuid = i_uid_into_vfsuid(mnt_userns, inode);
if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
goto check_perm;
break;
case ACL_USER:
uid = mapped_kuid_fs(mnt_userns,
i_user_ns(inode),
vfsuid = make_vfsuid(mnt_userns, &init_user_ns,
pa->e_uid);
if (uid_eq(uid, current_fsuid()))
if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
goto mask;
break;
case ACL_GROUP_OBJ:
gid = i_gid_into_mnt(mnt_userns, inode);
if (in_group_p(gid)) {
vfsgid = i_gid_into_vfsgid(mnt_userns, inode);
if (vfsgid_in_group_p(vfsgid)) {
found = 1;
if ((pa->e_perm & want) == want)
goto mask;
}
break;
case ACL_GROUP:
gid = mapped_kgid_fs(mnt_userns,
i_user_ns(inode),
vfsgid = make_vfsgid(mnt_userns, &init_user_ns,
pa->e_gid);
if (in_group_p(gid)) {
if (vfsgid_in_group_p(vfsgid)) {
found = 1;
if ((pa->e_perm & want) == want)
goto mask;
......@@ -699,7 +698,7 @@ int posix_acl_update_mode(struct user_namespace *mnt_userns,
return error;
if (error == 0)
*acl = NULL;
if (!in_group_p(i_gid_into_mnt(mnt_userns, inode)) &&
if (!vfsgid_in_group_p(i_gid_into_vfsgid(mnt_userns, inode)) &&
!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
mode &= ~S_ISGID;
*mode_p = mode;
......@@ -710,46 +709,127 @@ EXPORT_SYMBOL(posix_acl_update_mode);
/*
* Fix up the uids and gids in posix acl extended attributes in place.
*/
static void posix_acl_fix_xattr_userns(
struct user_namespace *to, struct user_namespace *from,
struct user_namespace *mnt_userns,
void *value, size_t size, bool from_user)
static int posix_acl_fix_xattr_common(void *value, size_t size)
{
struct posix_acl_xattr_header *header = value;
int count;
if (!header)
return -EINVAL;
if (size < sizeof(struct posix_acl_xattr_header))
return -EINVAL;
if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
return -EINVAL;
count = posix_acl_xattr_count(size);
if (count < 0)
return -EINVAL;
if (count == 0)
return -EINVAL;
return count;
}
void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
const struct inode *inode,
void *value, size_t size)
{
struct posix_acl_xattr_header *header = value;
struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
int count;
vfsuid_t vfsuid;
vfsgid_t vfsgid;
kuid_t uid;
kgid_t gid;
if (!value)
if (no_idmapping(mnt_userns, i_user_ns(inode)))
return;
if (size < sizeof(struct posix_acl_xattr_header))
count = posix_acl_fix_xattr_common(value, size);
if (count < 0)
return;
if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
for (end = entry + count; entry != end; entry++) {
switch (le16_to_cpu(entry->e_tag)) {
case ACL_USER:
uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id));
vfsuid = make_vfsuid(mnt_userns, &init_user_ns, uid);
entry->e_id = cpu_to_le32(from_kuid(&init_user_ns,
vfsuid_into_kuid(vfsuid)));
break;
case ACL_GROUP:
gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id));
vfsgid = make_vfsgid(mnt_userns, &init_user_ns, gid);
entry->e_id = cpu_to_le32(from_kgid(&init_user_ns,
vfsgid_into_kgid(vfsgid)));
break;
default:
break;
}
}
}
void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
const struct inode *inode,
void *value, size_t size)
{
struct posix_acl_xattr_header *header = value;
struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
int count;
vfsuid_t vfsuid;
vfsgid_t vfsgid;
kuid_t uid;
kgid_t gid;
if (no_idmapping(mnt_userns, i_user_ns(inode)))
return;
count = posix_acl_xattr_count(size);
count = posix_acl_fix_xattr_common(value, size);
if (count < 0)
return;
if (count == 0)
for (end = entry + count; entry != end; entry++) {
switch (le16_to_cpu(entry->e_tag)) {
case ACL_USER:
uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id));
vfsuid = VFSUIDT_INIT(uid);
uid = from_vfsuid(mnt_userns, &init_user_ns, vfsuid);
entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, uid));
break;
case ACL_GROUP:
gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id));
vfsgid = VFSGIDT_INIT(gid);
gid = from_vfsgid(mnt_userns, &init_user_ns, vfsgid);
entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, gid));
break;
default:
break;
}
}
}
static void posix_acl_fix_xattr_userns(
struct user_namespace *to, struct user_namespace *from,
void *value, size_t size)
{
struct posix_acl_xattr_header *header = value;
struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
int count;
kuid_t uid;
kgid_t gid;
count = posix_acl_fix_xattr_common(value, size);
if (count < 0)
return;
for (end = entry + count; entry != end; entry++) {
switch(le16_to_cpu(entry->e_tag)) {
case ACL_USER:
uid = make_kuid(from, le32_to_cpu(entry->e_id));
if (from_user)
uid = mapped_kuid_user(mnt_userns, &init_user_ns, uid);
else
uid = mapped_kuid_fs(mnt_userns, &init_user_ns, uid);
entry->e_id = cpu_to_le32(from_kuid(to, uid));
break;
case ACL_GROUP:
gid = make_kgid(from, le32_to_cpu(entry->e_id));
if (from_user)
gid = mapped_kgid_user(mnt_userns, &init_user_ns, gid);
else
gid = mapped_kgid_fs(mnt_userns, &init_user_ns, gid);
entry->e_id = cpu_to_le32(from_kgid(to, gid));
break;
default:
......@@ -758,34 +838,20 @@ static void posix_acl_fix_xattr_userns(
}
}
void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
struct inode *inode,
void *value, size_t size)
void posix_acl_fix_xattr_from_user(void *value, size_t size)
{
struct user_namespace *user_ns = current_user_ns();
/* Leave ids untouched on non-idmapped mounts. */
if (no_idmapping(mnt_userns, i_user_ns(inode)))
mnt_userns = &init_user_ns;
if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
if (user_ns == &init_user_ns)
return;
posix_acl_fix_xattr_userns(&init_user_ns, user_ns, mnt_userns, value,
size, true);
posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
}
void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
struct inode *inode,
void *value, size_t size)
void posix_acl_fix_xattr_to_user(void *value, size_t size)
{
struct user_namespace *user_ns = current_user_ns();
/* Leave ids untouched on non-idmapped mounts. */
if (no_idmapping(mnt_userns, i_user_ns(inode)))
mnt_userns = &init_user_ns;
if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
if (user_ns == &init_user_ns)
return;
posix_acl_fix_xattr_userns(user_ns, &init_user_ns, mnt_userns, value,
size, false);
posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
}
/*
......
......@@ -282,9 +282,15 @@ __vfs_setxattr_locked(struct user_namespace *mnt_userns, struct dentry *dentry,
}
EXPORT_SYMBOL_GPL(__vfs_setxattr_locked);
static inline bool is_posix_acl_xattr(const char *name)
{
return (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
(strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0);
}
int
vfs_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
const char *name, const void *value, size_t size, int flags)
const char *name, void *value, size_t size, int flags)
{
struct inode *inode = dentry->d_inode;
struct inode *delegated_inode = NULL;
......@@ -292,12 +298,16 @@ vfs_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
int error;
if (size && strcmp(name, XATTR_NAME_CAPS) == 0) {
error = cap_convert_nscap(mnt_userns, dentry, &value, size);
error = cap_convert_nscap(mnt_userns, dentry,
(const void **)&value, size);
if (error < 0)
return error;
size = error;
}
if (size && is_posix_acl_xattr(name))
posix_acl_setxattr_idmapped_mnt(mnt_userns, inode, value, size);
retry_deleg:
inode_lock(inode);
error = __vfs_setxattr_locked(mnt_userns, dentry, name, value, size,
......@@ -431,7 +441,10 @@ vfs_getxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
return ret;
}
nolsm:
return __vfs_getxattr(dentry, inode, name, value, size);
error = __vfs_getxattr(dentry, inode, name, value, size);
if (error > 0 && is_posix_acl_xattr(name))
posix_acl_getxattr_idmapped_mnt(mnt_userns, inode, value, size);
return error;
}
EXPORT_SYMBOL_GPL(vfs_getxattr);
......@@ -577,8 +590,7 @@ static void setxattr_convert(struct user_namespace *mnt_userns,
if (ctx->size &&
((strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
(strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)))
posix_acl_fix_xattr_from_user(mnt_userns, d_inode(d),
ctx->kvalue, ctx->size);
posix_acl_fix_xattr_from_user(ctx->kvalue, ctx->size);
}
int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
......@@ -695,8 +707,7 @@ do_getxattr(struct user_namespace *mnt_userns, struct dentry *d,
if (error > 0) {
if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
(strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
posix_acl_fix_xattr_to_user(mnt_userns, d_inode(d),
ctx->kvalue, error);
posix_acl_fix_xattr_to_user(ctx->kvalue, error);
if (ctx->size && copy_to_user(ctx->value, ctx->kvalue, error))
error = -EFAULT;
} else if (error == -ERANGE && ctx->size >= XATTR_SIZE_MAX) {
......
......@@ -333,6 +333,19 @@ static inline bool vfsuid_has_fsmapping(struct user_namespace *mnt_userns,
return uid_valid(from_vfsuid(mnt_userns, fs_userns, vfsuid));
}
/**
* vfsuid_into_kuid - convert vfsuid into kuid
* @vfsuid: the vfsuid to convert
*
* This can be used when a vfsuid is committed as a kuid.
*
* Return: a kuid with the value of @vfsuid
*/
static inline kuid_t vfsuid_into_kuid(vfsuid_t vfsuid)
{
return AS_KUIDT(vfsuid);
}
/**
* from_vfsgid - map a vfsgid into the filesystem idmapping
* @mnt_userns: the mount's idmapping
......@@ -406,6 +419,19 @@ static inline bool vfsgid_has_fsmapping(struct user_namespace *mnt_userns,
return gid_valid(from_vfsgid(mnt_userns, fs_userns, vfsgid));
}
/**
* vfsgid_into_kgid - convert vfsgid into kgid
* @vfsgid: the vfsgid to convert
*
* This can be used when a vfsgid is committed as a kgid.
*
* Return: a kgid with the value of @vfsgid
*/
static inline kgid_t vfsgid_into_kgid(vfsgid_t vfsgid)
{
return AS_KGIDT(vfsgid);
}
/**
* mapped_fsuid - return caller's fsuid mapped up into a mnt_userns
* @mnt_userns: the mount's idmapping
......
......@@ -73,6 +73,7 @@ extern int set_posix_acl(struct user_namespace *, struct inode *, int,
struct posix_acl *);
struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type);
struct posix_acl *posix_acl_clone(const struct posix_acl *acl, gfp_t flags);
#ifdef CONFIG_FS_POSIX_ACL
int posix_acl_chmod(struct user_namespace *, struct inode *, umode_t);
......
......@@ -33,21 +33,31 @@ posix_acl_xattr_count(size_t size)
}
#ifdef CONFIG_FS_POSIX_ACL
void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
struct inode *inode,
void *value, size_t size);
void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
struct inode *inode,
void *value, size_t size);
void posix_acl_fix_xattr_from_user(void *value, size_t size);
void posix_acl_fix_xattr_to_user(void *value, size_t size);
void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
const struct inode *inode,
void *value, size_t size);
void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
const struct inode *inode,
void *value, size_t size);
#else
static inline void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
struct inode *inode,
void *value, size_t size)
static inline void posix_acl_fix_xattr_from_user(void *value, size_t size)
{
}
static inline void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
struct inode *inode,
void *value, size_t size)
static inline void posix_acl_fix_xattr_to_user(void *value, size_t size)
{
}
static inline void
posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
const struct inode *inode, void *value,
size_t size)
{
}
static inline void
posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
const struct inode *inode, void *value,
size_t size)
{
}
#endif
......
......@@ -61,7 +61,7 @@ int __vfs_setxattr_locked(struct user_namespace *, struct dentry *,
const char *, const void *, size_t, int,
struct inode **);
int vfs_setxattr(struct user_namespace *, struct dentry *, const char *,
const void *, size_t, int);
void *, size_t, int);
int __vfs_removexattr(struct user_namespace *, struct dentry *, const char *);
int __vfs_removexattr_locked(struct user_namespace *, struct dentry *,
const char *, struct inode **);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment