aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-11-03 10:44:44 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-16 12:16:49 -0500
commit1c7c474c31aea6d5cb2fb35f31d9e9e91ae466b1 (patch)
tree89a5fd1146be1744ce3ac94789542841512315b8 /mm
parent431547b3c4533b8c7fd150ab36980b9a3147797b (diff)
make generic_acl slightly more generic
Now that we cache the ACL pointers in the generic inode all the generic_acl cruft can go away and generic_acl.c can directly implement xattr handlers dealing with the full Posix ACL semantics for in-memory filesystems. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r--mm/Makefile1
-rw-r--r--mm/shmem.c17
-rw-r--r--mm/shmem_acl.c133
3 files changed, 10 insertions, 141 deletions
diff --git a/mm/Makefile b/mm/Makefile
index 82131d0f8d85..7a68d2ab5560 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_HUGETLBFS) += hugetlb.o
22obj-$(CONFIG_NUMA) += mempolicy.o 22obj-$(CONFIG_NUMA) += mempolicy.o
23obj-$(CONFIG_SPARSEMEM) += sparse.o 23obj-$(CONFIG_SPARSEMEM) += sparse.o
24obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o 24obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o
25obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
26obj-$(CONFIG_SLOB) += slob.o 25obj-$(CONFIG_SLOB) += slob.o
27obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o 26obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o
28obj-$(CONFIG_KSM) += ksm.o 27obj-$(CONFIG_KSM) += ksm.o
diff --git a/mm/shmem.c b/mm/shmem.c
index 3cd32c2ea0a0..f8485062f3ba 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -41,6 +41,7 @@ static struct vfsmount *shm_mnt;
41 41
42#include <linux/xattr.h> 42#include <linux/xattr.h>
43#include <linux/exportfs.h> 43#include <linux/exportfs.h>
44#include <linux/posix_acl.h>
44#include <linux/generic_acl.h> 45#include <linux/generic_acl.h>
45#include <linux/mman.h> 46#include <linux/mman.h>
46#include <linux/string.h> 47#include <linux/string.h>
@@ -809,7 +810,7 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
809 error = inode_setattr(inode, attr); 810 error = inode_setattr(inode, attr);
810#ifdef CONFIG_TMPFS_POSIX_ACL 811#ifdef CONFIG_TMPFS_POSIX_ACL
811 if (!error && (attr->ia_valid & ATTR_MODE)) 812 if (!error && (attr->ia_valid & ATTR_MODE))
812 error = generic_acl_chmod(inode, &shmem_acl_ops); 813 error = generic_acl_chmod(inode);
813#endif 814#endif
814 if (page) 815 if (page)
815 page_cache_release(page); 816 page_cache_release(page);
@@ -1823,11 +1824,13 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1823 return error; 1824 return error;
1824 } 1825 }
1825 } 1826 }
1826 error = shmem_acl_init(inode, dir); 1827#ifdef CONFIG_TMPFS_POSIX_ACL
1828 error = generic_acl_init(inode, dir);
1827 if (error) { 1829 if (error) {
1828 iput(inode); 1830 iput(inode);
1829 return error; 1831 return error;
1830 } 1832 }
1833#endif
1831 if (dir->i_mode & S_ISGID) { 1834 if (dir->i_mode & S_ISGID) {
1832 inode->i_gid = dir->i_gid; 1835 inode->i_gid = dir->i_gid;
1833 if (S_ISDIR(mode)) 1836 if (S_ISDIR(mode))
@@ -2074,8 +2077,8 @@ static struct xattr_handler shmem_xattr_security_handler = {
2074}; 2077};
2075 2078
2076static struct xattr_handler *shmem_xattr_handlers[] = { 2079static struct xattr_handler *shmem_xattr_handlers[] = {
2077 &shmem_xattr_acl_access_handler, 2080 &generic_acl_access_handler,
2078 &shmem_xattr_acl_default_handler, 2081 &generic_acl_default_handler,
2079 &shmem_xattr_security_handler, 2082 &shmem_xattr_security_handler,
2080 NULL 2083 NULL
2081}; 2084};
@@ -2454,7 +2457,7 @@ static const struct inode_operations shmem_inode_operations = {
2454 .getxattr = generic_getxattr, 2457 .getxattr = generic_getxattr,
2455 .listxattr = generic_listxattr, 2458 .listxattr = generic_listxattr,
2456 .removexattr = generic_removexattr, 2459 .removexattr = generic_removexattr,
2457 .check_acl = shmem_check_acl, 2460 .check_acl = generic_check_acl,
2458#endif 2461#endif
2459 2462
2460}; 2463};
@@ -2477,7 +2480,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
2477 .getxattr = generic_getxattr, 2480 .getxattr = generic_getxattr,
2478 .listxattr = generic_listxattr, 2481 .listxattr = generic_listxattr,
2479 .removexattr = generic_removexattr, 2482 .removexattr = generic_removexattr,
2480 .check_acl = shmem_check_acl, 2483 .check_acl = generic_check_acl,
2481#endif 2484#endif
2482}; 2485};
2483 2486
@@ -2488,7 +2491,7 @@ static const struct inode_operations shmem_special_inode_operations = {
2488 .getxattr = generic_getxattr, 2491 .getxattr = generic_getxattr,
2489 .listxattr = generic_listxattr, 2492 .listxattr = generic_listxattr,
2490 .removexattr = generic_removexattr, 2493 .removexattr = generic_removexattr,
2491 .check_acl = shmem_check_acl, 2494 .check_acl = generic_check_acl,
2492#endif 2495#endif
2493}; 2496};
2494 2497
diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c
deleted file mode 100644
index f8d5330ec0d7..000000000000
--- a/mm/shmem_acl.c
+++ /dev/null
@@ -1,133 +0,0 @@
1/*
2 * mm/shmem_acl.c
3 *
4 * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
5 *
6 * This file is released under the GPL.
7 */
8
9#include <linux/fs.h>
10#include <linux/shmem_fs.h>
11#include <linux/xattr.h>
12#include <linux/generic_acl.h>
13
14/**
15 * shmem_get_acl - generic_acl_operations->getacl() operation
16 */
17static struct posix_acl *
18shmem_get_acl(struct inode *inode, int type)
19{
20 struct posix_acl *acl = NULL;
21
22 spin_lock(&inode->i_lock);
23 switch(type) {
24 case ACL_TYPE_ACCESS:
25 acl = posix_acl_dup(inode->i_acl);
26 break;
27
28 case ACL_TYPE_DEFAULT:
29 acl = posix_acl_dup(inode->i_default_acl);
30 break;
31 }
32 spin_unlock(&inode->i_lock);
33
34 return acl;
35}
36
37/**
38 * shmem_set_acl - generic_acl_operations->setacl() operation
39 */
40static void
41shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl)
42{
43 struct posix_acl *free = NULL;
44
45 spin_lock(&inode->i_lock);
46 switch(type) {
47 case ACL_TYPE_ACCESS:
48 free = inode->i_acl;
49 inode->i_acl = posix_acl_dup(acl);
50 break;
51
52 case ACL_TYPE_DEFAULT:
53 free = inode->i_default_acl;
54 inode->i_default_acl = posix_acl_dup(acl);
55 break;
56 }
57 spin_unlock(&inode->i_lock);
58 posix_acl_release(free);
59}
60
61struct generic_acl_operations shmem_acl_ops = {
62 .getacl = shmem_get_acl,
63 .setacl = shmem_set_acl,
64};
65
66static size_t
67shmem_xattr_list_acl(struct dentry *dentry, char *list, size_t list_size,
68 const char *name, size_t name_len, int type)
69{
70 return generic_acl_list(dentry->d_inode, &shmem_acl_ops,
71 type, list, list_size);
72}
73
74static int
75shmem_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
76 size_t size, int type)
77{
78 if (strcmp(name, "") != 0)
79 return -EINVAL;
80 return generic_acl_get(dentry->d_inode, &shmem_acl_ops, type,
81 buffer, size);
82}
83
84static int
85shmem_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
86 size_t size, int flags, int type)
87{
88 if (strcmp(name, "") != 0)
89 return -EINVAL;
90 return generic_acl_set(dentry->d_inode, &shmem_acl_ops, type,
91 value, size);
92}
93
94struct xattr_handler shmem_xattr_acl_access_handler = {
95 .prefix = POSIX_ACL_XATTR_ACCESS,
96 .flags = ACL_TYPE_ACCESS,
97 .list = shmem_xattr_list_acl,
98 .get = shmem_xattr_get_acl,
99 .set = shmem_xattr_set_acl,
100};
101
102struct xattr_handler shmem_xattr_acl_default_handler = {
103 .prefix = POSIX_ACL_XATTR_DEFAULT,
104 .flags = ACL_TYPE_DEFAULT,
105 .list = shmem_xattr_list_acl,
106 .get = shmem_xattr_get_acl,
107 .set = shmem_xattr_set_acl,
108};
109
110/**
111 * shmem_acl_init - Inizialize the acl(s) of a new inode
112 */
113int
114shmem_acl_init(struct inode *inode, struct inode *dir)
115{
116 return generic_acl_init(inode, dir, &shmem_acl_ops);
117}
118
119/**
120 * shmem_check_acl - check_acl() callback for generic_permission()
121 */
122int
123shmem_check_acl(struct inode *inode, int mask)
124{
125 struct posix_acl *acl = shmem_get_acl(inode, ACL_TYPE_ACCESS);
126
127 if (acl) {
128 int error = posix_acl_permission(inode, acl, mask);
129 posix_acl_release(acl);
130 return error;
131 }
132 return -EAGAIN;
133}