fs: remove generic_acl

And instead convert tmpfs to use the new generic ACL code, with two stub
methods provided for in-memory filesystems.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Christoph Hellwig 2013-12-20 05:16:54 -08:00 committed by Al Viro
parent 013cdf1088
commit feda821e76
7 changed files with 69 additions and 238 deletions

View File

@ -68,10 +68,6 @@ source "fs/quota/Kconfig"
source "fs/autofs4/Kconfig" source "fs/autofs4/Kconfig"
source "fs/fuse/Kconfig" source "fs/fuse/Kconfig"
config GENERIC_ACL
bool
select FS_POSIX_ACL
menu "Caches" menu "Caches"
source "fs/fscache/Kconfig" source "fs/fscache/Kconfig"
@ -119,7 +115,7 @@ config TMPFS_POSIX_ACL
bool "Tmpfs POSIX Access Control Lists" bool "Tmpfs POSIX Access Control Lists"
depends on TMPFS depends on TMPFS
select TMPFS_XATTR select TMPFS_XATTR
select GENERIC_ACL select FS_POSIX_ACL
help help
POSIX Access Control Lists (ACLs) support additional access rights POSIX Access Control Lists (ACLs) support additional access rights
for users and groups beyond the standard owner/group/world scheme, for users and groups beyond the standard owner/group/world scheme,

View File

@ -44,7 +44,6 @@ obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
obj-$(CONFIG_FS_MBCACHE) += mbcache.o obj-$(CONFIG_FS_MBCACHE) += mbcache.o
obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
obj-$(CONFIG_NFS_COMMON) += nfs_common/ obj-$(CONFIG_NFS_COMMON) += nfs_common/
obj-$(CONFIG_GENERIC_ACL) += generic_acl.o
obj-$(CONFIG_COREDUMP) += coredump.o obj-$(CONFIG_COREDUMP) += coredump.o
obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_SYSCTL) += drop_caches.o

View File

@ -1,184 +0,0 @@
/*
* (C) 2005 Andreas Gruenbacher <agruen@suse.de>
*
* This file is released under the GPL.
*
* Generic ACL support for in-memory filesystems.
*/
#include <linux/sched.h>
#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/generic_acl.h>
#include <linux/posix_acl.h>
#include <linux/posix_acl_xattr.h>
static size_t
generic_acl_list(struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len, int type)
{
struct posix_acl *acl;
const char *xname;
size_t size;
acl = get_cached_acl(dentry->d_inode, type);
if (!acl)
return 0;
posix_acl_release(acl);
switch (type) {
case ACL_TYPE_ACCESS:
xname = POSIX_ACL_XATTR_ACCESS;
break;
case ACL_TYPE_DEFAULT:
xname = POSIX_ACL_XATTR_DEFAULT;
break;
default:
return 0;
}
size = strlen(xname) + 1;
if (list && size <= list_size)
memcpy(list, xname, size);
return size;
}
static int
generic_acl_get(struct dentry *dentry, const char *name, void *buffer,
size_t size, int type)
{
struct posix_acl *acl;
int error;
if (strcmp(name, "") != 0)
return -EINVAL;
acl = get_cached_acl(dentry->d_inode, type);
if (!acl)
return -ENODATA;
error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
posix_acl_release(acl);
return error;
}
static int
generic_acl_set(struct dentry *dentry, const char *name, const void *value,
size_t size, int flags, int type)
{
struct inode *inode = dentry->d_inode;
struct posix_acl *acl = NULL;
int error;
if (strcmp(name, "") != 0)
return -EINVAL;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
if (!inode_owner_or_capable(inode))
return -EPERM;
if (value) {
acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (IS_ERR(acl))
return PTR_ERR(acl);
}
if (acl) {
error = posix_acl_valid(acl);
if (error)
goto failed;
switch (type) {
case ACL_TYPE_ACCESS:
error = posix_acl_equiv_mode(acl, &inode->i_mode);
if (error < 0)
goto failed;
inode->i_ctime = CURRENT_TIME;
if (error == 0) {
posix_acl_release(acl);
acl = NULL;
}
break;
case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode)) {
error = -EINVAL;
goto failed;
}
break;
}
}
set_cached_acl(inode, type, acl);
error = 0;
failed:
posix_acl_release(acl);
return error;
}
/**
* generic_acl_init - Take care of acl inheritance at @inode create time
*
* Files created inside a directory with a default ACL inherit the
* directory's default ACL.
*/
int
generic_acl_init(struct inode *inode, struct inode *dir)
{
struct posix_acl *acl = NULL;
int error;
if (!S_ISLNK(inode->i_mode))
acl = get_cached_acl(dir, ACL_TYPE_DEFAULT);
if (acl) {
if (S_ISDIR(inode->i_mode))
set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
if (error < 0)
return error;
if (error > 0)
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
} else {
inode->i_mode &= ~current_umask();
}
error = 0;
posix_acl_release(acl);
return error;
}
/**
* generic_acl_chmod - change the access acl of @inode upon chmod()
*
* A chmod also changes the permissions of the owner, group/mask, and
* other ACL entries.
*/
int
generic_acl_chmod(struct inode *inode)
{
struct posix_acl *acl;
int error = 0;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
if (acl) {
error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
if (error)
return error;
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
posix_acl_release(acl);
}
return error;
}
const struct xattr_handler generic_acl_access_handler = {
.prefix = POSIX_ACL_XATTR_ACCESS,
.flags = ACL_TYPE_ACCESS,
.list = generic_acl_list,
.get = generic_acl_get,
.set = generic_acl_set,
};
const struct xattr_handler generic_acl_default_handler = {
.prefix = POSIX_ACL_XATTR_DEFAULT,
.flags = ACL_TYPE_DEFAULT,
.list = generic_acl_list,
.get = generic_acl_get,
.set = generic_acl_set,
};

View File

@ -786,3 +786,39 @@ const struct xattr_handler posix_acl_default_xattr_handler = {
.set = posix_acl_xattr_set, .set = posix_acl_xattr_set,
}; };
EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler); EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler);
int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
int error;
if (type == ACL_TYPE_ACCESS) {
error = posix_acl_equiv_mode(acl, &inode->i_mode);
if (error < 0)
return 0;
if (error == 0)
acl = NULL;
}
inode->i_ctime = CURRENT_TIME;
set_cached_acl(inode, type, acl);
return 0;
}
int simple_acl_create(struct inode *dir, struct inode *inode)
{
struct posix_acl *default_acl, *acl;
int error;
error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
if (error)
return error;
set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
if (default_acl)
posix_acl_release(default_acl);
if (acl)
posix_acl_release(acl);
return 0;
}

View File

@ -1,14 +0,0 @@
#ifndef LINUX_GENERIC_ACL_H
#define LINUX_GENERIC_ACL_H
#include <linux/xattr.h>
struct inode;
extern const struct xattr_handler generic_acl_access_handler;
extern const struct xattr_handler generic_acl_default_handler;
int generic_acl_init(struct inode *, struct inode *);
int generic_acl_chmod(struct inode *);
#endif /* LINUX_GENERIC_ACL_H */

View File

@ -99,6 +99,9 @@ extern int posix_acl_chmod(struct inode *, umode_t);
extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
struct posix_acl **); struct posix_acl **);
extern int simple_set_acl(struct inode *, struct posix_acl *, int);
extern int simple_acl_create(struct inode *, struct inode *);
static inline struct posix_acl **acl_by_type(struct inode *inode, int type) static inline struct posix_acl **acl_by_type(struct inode *inode, int type)
{ {
switch (type) { switch (type) {
@ -181,6 +184,12 @@ static inline int posix_acl_chmod(struct inode *inode, umode_t mode)
return 0; return 0;
} }
#define simple_set_acl NULL
static inline int simple_acl_create(struct inode *dir, struct inode *inode)
{
return 0;
}
static inline void cache_no_acl(struct inode *inode) static inline void cache_no_acl(struct inode *inode)
{ {
} }

View File

@ -45,7 +45,7 @@ static struct vfsmount *shm_mnt;
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/exportfs.h> #include <linux/exportfs.h>
#include <linux/posix_acl.h> #include <linux/posix_acl.h>
#include <linux/generic_acl.h> #include <linux/posix_acl_xattr.h>
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -620,10 +620,8 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
} }
setattr_copy(inode, attr); setattr_copy(inode, attr);
#ifdef CONFIG_TMPFS_POSIX_ACL
if (attr->ia_valid & ATTR_MODE) if (attr->ia_valid & ATTR_MODE)
error = generic_acl_chmod(inode); error = posix_acl_chmod(inode, inode->i_mode);
#endif
return error; return error;
} }
@ -1937,22 +1935,14 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
if (inode) { if (inode) {
#ifdef CONFIG_TMPFS_POSIX_ACL error = simple_acl_create(dir, inode);
error = generic_acl_init(inode, dir); if (error)
if (error) { goto out_iput;
iput(inode);
return error;
}
#endif
error = security_inode_init_security(inode, dir, error = security_inode_init_security(inode, dir,
&dentry->d_name, &dentry->d_name,
shmem_initxattrs, NULL); shmem_initxattrs, NULL);
if (error) { if (error && error != -EOPNOTSUPP)
if (error != -EOPNOTSUPP) { goto out_iput;
iput(inode);
return error;
}
}
error = 0; error = 0;
dir->i_size += BOGO_DIRENT_SIZE; dir->i_size += BOGO_DIRENT_SIZE;
@ -1961,6 +1951,9 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
dget(dentry); /* Extra count - pin the dentry in core */ dget(dentry); /* Extra count - pin the dentry in core */
} }
return error; return error;
out_iput:
iput(inode);
return error;
} }
static int static int
@ -1974,24 +1967,17 @@ shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
error = security_inode_init_security(inode, dir, error = security_inode_init_security(inode, dir,
NULL, NULL,
shmem_initxattrs, NULL); shmem_initxattrs, NULL);
if (error) { if (error && error != -EOPNOTSUPP)
if (error != -EOPNOTSUPP) { goto out_iput;
iput(inode); error = simple_acl_create(dir, inode);
return error; if (error)
} goto out_iput;
}
#ifdef CONFIG_TMPFS_POSIX_ACL
error = generic_acl_init(inode, dir);
if (error) {
iput(inode);
return error;
}
#else
error = 0;
#endif
d_tmpfile(dentry, inode); d_tmpfile(dentry, inode);
} }
return error; return error;
out_iput:
iput(inode);
return error;
} }
static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
@ -2223,8 +2209,8 @@ static int shmem_initxattrs(struct inode *inode,
static const struct xattr_handler *shmem_xattr_handlers[] = { static const struct xattr_handler *shmem_xattr_handlers[] = {
#ifdef CONFIG_TMPFS_POSIX_ACL #ifdef CONFIG_TMPFS_POSIX_ACL
&generic_acl_access_handler, &posix_acl_access_xattr_handler,
&generic_acl_default_handler, &posix_acl_default_xattr_handler,
#endif #endif
NULL NULL
}; };
@ -2740,6 +2726,7 @@ static const struct inode_operations shmem_inode_operations = {
.getxattr = shmem_getxattr, .getxattr = shmem_getxattr,
.listxattr = shmem_listxattr, .listxattr = shmem_listxattr,
.removexattr = shmem_removexattr, .removexattr = shmem_removexattr,
.set_acl = simple_set_acl,
#endif #endif
}; };
@ -2764,6 +2751,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
#endif #endif
#ifdef CONFIG_TMPFS_POSIX_ACL #ifdef CONFIG_TMPFS_POSIX_ACL
.setattr = shmem_setattr, .setattr = shmem_setattr,
.set_acl = simple_set_acl,
#endif #endif
}; };
@ -2776,6 +2764,7 @@ static const struct inode_operations shmem_special_inode_operations = {
#endif #endif
#ifdef CONFIG_TMPFS_POSIX_ACL #ifdef CONFIG_TMPFS_POSIX_ACL
.setattr = shmem_setattr, .setattr = shmem_setattr,
.set_acl = simple_set_acl,
#endif #endif
}; };