aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/Kconfig6
-rw-r--r--fs/Makefile1
-rw-r--r--fs/generic_acl.c184
-rw-r--r--fs/posix_acl.c36
-rw-r--r--include/linux/generic_acl.h14
-rw-r--r--include/linux/posix_acl.h9
-rw-r--r--mm/shmem.c57
7 files changed, 69 insertions, 238 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index c229f828eb01..7385e54be4b9 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -68,10 +68,6 @@ source "fs/quota/Kconfig"
68source "fs/autofs4/Kconfig" 68source "fs/autofs4/Kconfig"
69source "fs/fuse/Kconfig" 69source "fs/fuse/Kconfig"
70 70
71config GENERIC_ACL
72 bool
73 select FS_POSIX_ACL
74
75menu "Caches" 71menu "Caches"
76 72
77source "fs/fscache/Kconfig" 73source "fs/fscache/Kconfig"
@@ -119,7 +115,7 @@ config TMPFS_POSIX_ACL
119 bool "Tmpfs POSIX Access Control Lists" 115 bool "Tmpfs POSIX Access Control Lists"
120 depends on TMPFS 116 depends on TMPFS
121 select TMPFS_XATTR 117 select TMPFS_XATTR
122 select GENERIC_ACL 118 select FS_POSIX_ACL
123 help 119 help
124 POSIX Access Control Lists (ACLs) support additional access rights 120 POSIX Access Control Lists (ACLs) support additional access rights
125 for users and groups beyond the standard owner/group/world scheme, 121 for users and groups beyond the standard owner/group/world scheme,
diff --git a/fs/Makefile b/fs/Makefile
index f2c1843820e3..5bebad4b01c6 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -44,7 +44,6 @@ obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
44obj-$(CONFIG_FS_MBCACHE) += mbcache.o 44obj-$(CONFIG_FS_MBCACHE) += mbcache.o
45obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o 45obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
46obj-$(CONFIG_NFS_COMMON) += nfs_common/ 46obj-$(CONFIG_NFS_COMMON) += nfs_common/
47obj-$(CONFIG_GENERIC_ACL) += generic_acl.o
48obj-$(CONFIG_COREDUMP) += coredump.o 47obj-$(CONFIG_COREDUMP) += coredump.o
49obj-$(CONFIG_SYSCTL) += drop_caches.o 48obj-$(CONFIG_SYSCTL) += drop_caches.o
50 49
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
deleted file mode 100644
index 4357f39c8441..000000000000
--- a/fs/generic_acl.c
+++ /dev/null
@@ -1,184 +0,0 @@
1/*
2 * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
3 *
4 * This file is released under the GPL.
5 *
6 * Generic ACL support for in-memory filesystems.
7 */
8
9#include <linux/sched.h>
10#include <linux/gfp.h>
11#include <linux/fs.h>
12#include <linux/generic_acl.h>
13#include <linux/posix_acl.h>
14#include <linux/posix_acl_xattr.h>
15
16
17static size_t
18generic_acl_list(struct dentry *dentry, char *list, size_t list_size,
19 const char *name, size_t name_len, int type)
20{
21 struct posix_acl *acl;
22 const char *xname;
23 size_t size;
24
25 acl = get_cached_acl(dentry->d_inode, type);
26 if (!acl)
27 return 0;
28 posix_acl_release(acl);
29
30 switch (type) {
31 case ACL_TYPE_ACCESS:
32 xname = POSIX_ACL_XATTR_ACCESS;
33 break;
34 case ACL_TYPE_DEFAULT:
35 xname = POSIX_ACL_XATTR_DEFAULT;
36 break;
37 default:
38 return 0;
39 }
40 size = strlen(xname) + 1;
41 if (list && size <= list_size)
42 memcpy(list, xname, size);
43 return size;
44}
45
46static int
47generic_acl_get(struct dentry *dentry, const char *name, void *buffer,
48 size_t size, int type)
49{
50 struct posix_acl *acl;
51 int error;
52
53 if (strcmp(name, "") != 0)
54 return -EINVAL;
55
56 acl = get_cached_acl(dentry->d_inode, type);
57 if (!acl)
58 return -ENODATA;
59 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
60 posix_acl_release(acl);
61
62 return error;
63}
64
65static int
66generic_acl_set(struct dentry *dentry, const char *name, const void *value,
67 size_t size, int flags, int type)
68{
69 struct inode *inode = dentry->d_inode;
70 struct posix_acl *acl = NULL;
71 int error;
72
73 if (strcmp(name, "") != 0)
74 return -EINVAL;
75 if (S_ISLNK(inode->i_mode))
76 return -EOPNOTSUPP;
77 if (!inode_owner_or_capable(inode))
78 return -EPERM;
79 if (value) {
80 acl = posix_acl_from_xattr(&init_user_ns, value, size);
81 if (IS_ERR(acl))
82 return PTR_ERR(acl);
83 }
84 if (acl) {
85 error = posix_acl_valid(acl);
86 if (error)
87 goto failed;
88 switch (type) {
89 case ACL_TYPE_ACCESS:
90 error = posix_acl_equiv_mode(acl, &inode->i_mode);
91 if (error < 0)
92 goto failed;
93 inode->i_ctime = CURRENT_TIME;
94 if (error == 0) {
95 posix_acl_release(acl);
96 acl = NULL;
97 }
98 break;
99 case ACL_TYPE_DEFAULT:
100 if (!S_ISDIR(inode->i_mode)) {
101 error = -EINVAL;
102 goto failed;
103 }
104 break;
105 }
106 }
107 set_cached_acl(inode, type, acl);
108 error = 0;
109failed:
110 posix_acl_release(acl);
111 return error;
112}
113
114/**
115 * generic_acl_init - Take care of acl inheritance at @inode create time
116 *
117 * Files created inside a directory with a default ACL inherit the
118 * directory's default ACL.
119 */
120int
121generic_acl_init(struct inode *inode, struct inode *dir)
122{
123 struct posix_acl *acl = NULL;
124 int error;
125
126 if (!S_ISLNK(inode->i_mode))
127 acl = get_cached_acl(dir, ACL_TYPE_DEFAULT);
128 if (acl) {
129 if (S_ISDIR(inode->i_mode))
130 set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
131 error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
132 if (error < 0)
133 return error;
134 if (error > 0)
135 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
136 } else {
137 inode->i_mode &= ~current_umask();
138 }
139 error = 0;
140
141 posix_acl_release(acl);
142 return error;
143}
144
145/**
146 * generic_acl_chmod - change the access acl of @inode upon chmod()
147 *
148 * A chmod also changes the permissions of the owner, group/mask, and
149 * other ACL entries.
150 */
151int
152generic_acl_chmod(struct inode *inode)
153{
154 struct posix_acl *acl;
155 int error = 0;
156
157 if (S_ISLNK(inode->i_mode))
158 return -EOPNOTSUPP;
159 acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
160 if (acl) {
161 error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
162 if (error)
163 return error;
164 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
165 posix_acl_release(acl);
166 }
167 return error;
168}
169
170const struct xattr_handler generic_acl_access_handler = {
171 .prefix = POSIX_ACL_XATTR_ACCESS,
172 .flags = ACL_TYPE_ACCESS,
173 .list = generic_acl_list,
174 .get = generic_acl_get,
175 .set = generic_acl_set,
176};
177
178const struct xattr_handler generic_acl_default_handler = {
179 .prefix = POSIX_ACL_XATTR_DEFAULT,
180 .flags = ACL_TYPE_DEFAULT,
181 .list = generic_acl_list,
182 .get = generic_acl_get,
183 .set = generic_acl_set,
184};
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 8f245ab20143..f40df9b665fb 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -786,3 +786,39 @@ const struct xattr_handler posix_acl_default_xattr_handler = {
786 .set = posix_acl_xattr_set, 786 .set = posix_acl_xattr_set,
787}; 787};
788EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler); 788EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler);
789
790int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type)
791{
792 int error;
793
794 if (type == ACL_TYPE_ACCESS) {
795 error = posix_acl_equiv_mode(acl, &inode->i_mode);
796 if (error < 0)
797 return 0;
798 if (error == 0)
799 acl = NULL;
800 }
801
802 inode->i_ctime = CURRENT_TIME;
803 set_cached_acl(inode, type, acl);
804 return 0;
805}
806
807int simple_acl_create(struct inode *dir, struct inode *inode)
808{
809 struct posix_acl *default_acl, *acl;
810 int error;
811
812 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
813 if (error)
814 return error;
815
816 set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
817 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
818
819 if (default_acl)
820 posix_acl_release(default_acl);
821 if (acl)
822 posix_acl_release(acl);
823 return 0;
824}
diff --git a/include/linux/generic_acl.h b/include/linux/generic_acl.h
deleted file mode 100644
index b6d657544ef1..000000000000
--- a/include/linux/generic_acl.h
+++ /dev/null
@@ -1,14 +0,0 @@
1#ifndef LINUX_GENERIC_ACL_H
2#define LINUX_GENERIC_ACL_H
3
4#include <linux/xattr.h>
5
6struct inode;
7
8extern const struct xattr_handler generic_acl_access_handler;
9extern const struct xattr_handler generic_acl_default_handler;
10
11int generic_acl_init(struct inode *, struct inode *);
12int generic_acl_chmod(struct inode *);
13
14#endif /* LINUX_GENERIC_ACL_H */
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 3d14be8e14db..6b12b3d57e90 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -99,6 +99,9 @@ extern int posix_acl_chmod(struct inode *, umode_t);
99extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, 99extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
100 struct posix_acl **); 100 struct posix_acl **);
101 101
102extern int simple_set_acl(struct inode *, struct posix_acl *, int);
103extern int simple_acl_create(struct inode *, struct inode *);
104
102static inline struct posix_acl **acl_by_type(struct inode *inode, int type) 105static inline struct posix_acl **acl_by_type(struct inode *inode, int type)
103{ 106{
104 switch (type) { 107 switch (type) {
@@ -181,6 +184,12 @@ static inline int posix_acl_chmod(struct inode *inode, umode_t mode)
181 return 0; 184 return 0;
182} 185}
183 186
187#define simple_set_acl NULL
188
189static inline int simple_acl_create(struct inode *dir, struct inode *inode)
190{
191 return 0;
192}
184static inline void cache_no_acl(struct inode *inode) 193static inline void cache_no_acl(struct inode *inode)
185{ 194{
186} 195}
diff --git a/mm/shmem.c b/mm/shmem.c
index 902a14842b74..b21ca543458c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -45,7 +45,7 @@ static struct vfsmount *shm_mnt;
45#include <linux/xattr.h> 45#include <linux/xattr.h>
46#include <linux/exportfs.h> 46#include <linux/exportfs.h>
47#include <linux/posix_acl.h> 47#include <linux/posix_acl.h>
48#include <linux/generic_acl.h> 48#include <linux/posix_acl_xattr.h>
49#include <linux/mman.h> 49#include <linux/mman.h>
50#include <linux/string.h> 50#include <linux/string.h>
51#include <linux/slab.h> 51#include <linux/slab.h>
@@ -620,10 +620,8 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
620 } 620 }
621 621
622 setattr_copy(inode, attr); 622 setattr_copy(inode, attr);
623#ifdef CONFIG_TMPFS_POSIX_ACL
624 if (attr->ia_valid & ATTR_MODE) 623 if (attr->ia_valid & ATTR_MODE)
625 error = generic_acl_chmod(inode); 624 error = posix_acl_chmod(inode, inode->i_mode);
626#endif
627 return error; 625 return error;
628} 626}
629 627
@@ -1937,22 +1935,14 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1937 1935
1938 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); 1936 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
1939 if (inode) { 1937 if (inode) {
1940#ifdef CONFIG_TMPFS_POSIX_ACL 1938 error = simple_acl_create(dir, inode);
1941 error = generic_acl_init(inode, dir); 1939 if (error)
1942 if (error) { 1940 goto out_iput;
1943 iput(inode);
1944 return error;
1945 }
1946#endif
1947 error = security_inode_init_security(inode, dir, 1941 error = security_inode_init_security(inode, dir,
1948 &dentry->d_name, 1942 &dentry->d_name,
1949 shmem_initxattrs, NULL); 1943 shmem_initxattrs, NULL);
1950 if (error) { 1944 if (error && error != -EOPNOTSUPP)
1951 if (error != -EOPNOTSUPP) { 1945 goto out_iput;
1952 iput(inode);
1953 return error;
1954 }
1955 }
1956 1946
1957 error = 0; 1947 error = 0;
1958 dir->i_size += BOGO_DIRENT_SIZE; 1948 dir->i_size += BOGO_DIRENT_SIZE;
@@ -1961,6 +1951,9 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1961 dget(dentry); /* Extra count - pin the dentry in core */ 1951 dget(dentry); /* Extra count - pin the dentry in core */
1962 } 1952 }
1963 return error; 1953 return error;
1954out_iput:
1955 iput(inode);
1956 return error;
1964} 1957}
1965 1958
1966static int 1959static int
@@ -1974,24 +1967,17 @@ shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
1974 error = security_inode_init_security(inode, dir, 1967 error = security_inode_init_security(inode, dir,
1975 NULL, 1968 NULL,
1976 shmem_initxattrs, NULL); 1969 shmem_initxattrs, NULL);
1977 if (error) { 1970 if (error && error != -EOPNOTSUPP)
1978 if (error != -EOPNOTSUPP) { 1971 goto out_iput;
1979 iput(inode); 1972 error = simple_acl_create(dir, inode);
1980 return error; 1973 if (error)
1981 } 1974 goto out_iput;
1982 }
1983#ifdef CONFIG_TMPFS_POSIX_ACL
1984 error = generic_acl_init(inode, dir);
1985 if (error) {
1986 iput(inode);
1987 return error;
1988 }
1989#else
1990 error = 0;
1991#endif
1992 d_tmpfile(dentry, inode); 1975 d_tmpfile(dentry, inode);
1993 } 1976 }
1994 return error; 1977 return error;
1978out_iput:
1979 iput(inode);
1980 return error;
1995} 1981}
1996 1982
1997static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 1983static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
@@ -2223,8 +2209,8 @@ static int shmem_initxattrs(struct inode *inode,
2223 2209
2224static const struct xattr_handler *shmem_xattr_handlers[] = { 2210static const struct xattr_handler *shmem_xattr_handlers[] = {
2225#ifdef CONFIG_TMPFS_POSIX_ACL 2211#ifdef CONFIG_TMPFS_POSIX_ACL
2226 &generic_acl_access_handler, 2212 &posix_acl_access_xattr_handler,
2227 &generic_acl_default_handler, 2213 &posix_acl_default_xattr_handler,
2228#endif 2214#endif
2229 NULL 2215 NULL
2230}; 2216};
@@ -2740,6 +2726,7 @@ static const struct inode_operations shmem_inode_operations = {
2740 .getxattr = shmem_getxattr, 2726 .getxattr = shmem_getxattr,
2741 .listxattr = shmem_listxattr, 2727 .listxattr = shmem_listxattr,
2742 .removexattr = shmem_removexattr, 2728 .removexattr = shmem_removexattr,
2729 .set_acl = simple_set_acl,
2743#endif 2730#endif
2744}; 2731};
2745 2732
@@ -2764,6 +2751,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
2764#endif 2751#endif
2765#ifdef CONFIG_TMPFS_POSIX_ACL 2752#ifdef CONFIG_TMPFS_POSIX_ACL
2766 .setattr = shmem_setattr, 2753 .setattr = shmem_setattr,
2754 .set_acl = simple_set_acl,
2767#endif 2755#endif
2768}; 2756};
2769 2757
@@ -2776,6 +2764,7 @@ static const struct inode_operations shmem_special_inode_operations = {
2776#endif 2764#endif
2777#ifdef CONFIG_TMPFS_POSIX_ACL 2765#ifdef CONFIG_TMPFS_POSIX_ACL
2778 .setattr = shmem_setattr, 2766 .setattr = shmem_setattr,
2767 .set_acl = simple_set_acl,
2779#endif 2768#endif
2780}; 2769};
2781 2770