diff options
-rw-r--r-- | fs/posix_acl.c | 84 | ||||
-rw-r--r-- | include/linux/posix_acl.h | 78 |
2 files changed, 85 insertions, 77 deletions
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 8bd2135b7f82..021e7c069b86 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -22,11 +22,80 @@ | |||
22 | 22 | ||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | 24 | ||
25 | EXPORT_SYMBOL(posix_acl_init); | 25 | struct posix_acl **acl_by_type(struct inode *inode, int type) |
26 | EXPORT_SYMBOL(posix_acl_alloc); | 26 | { |
27 | EXPORT_SYMBOL(posix_acl_valid); | 27 | switch (type) { |
28 | EXPORT_SYMBOL(posix_acl_equiv_mode); | 28 | case ACL_TYPE_ACCESS: |
29 | EXPORT_SYMBOL(posix_acl_from_mode); | 29 | return &inode->i_acl; |
30 | case ACL_TYPE_DEFAULT: | ||
31 | return &inode->i_default_acl; | ||
32 | default: | ||
33 | BUG(); | ||
34 | } | ||
35 | } | ||
36 | EXPORT_SYMBOL(acl_by_type); | ||
37 | |||
38 | struct posix_acl *get_cached_acl(struct inode *inode, int type) | ||
39 | { | ||
40 | struct posix_acl **p = acl_by_type(inode, type); | ||
41 | struct posix_acl *acl = ACCESS_ONCE(*p); | ||
42 | if (acl) { | ||
43 | spin_lock(&inode->i_lock); | ||
44 | acl = *p; | ||
45 | if (acl != ACL_NOT_CACHED) | ||
46 | acl = posix_acl_dup(acl); | ||
47 | spin_unlock(&inode->i_lock); | ||
48 | } | ||
49 | return acl; | ||
50 | } | ||
51 | EXPORT_SYMBOL(get_cached_acl); | ||
52 | |||
53 | struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) | ||
54 | { | ||
55 | return rcu_dereference(*acl_by_type(inode, type)); | ||
56 | } | ||
57 | EXPORT_SYMBOL(get_cached_acl_rcu); | ||
58 | |||
59 | void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl) | ||
60 | { | ||
61 | struct posix_acl **p = acl_by_type(inode, type); | ||
62 | struct posix_acl *old; | ||
63 | spin_lock(&inode->i_lock); | ||
64 | old = *p; | ||
65 | rcu_assign_pointer(*p, posix_acl_dup(acl)); | ||
66 | spin_unlock(&inode->i_lock); | ||
67 | if (old != ACL_NOT_CACHED) | ||
68 | posix_acl_release(old); | ||
69 | } | ||
70 | EXPORT_SYMBOL(set_cached_acl); | ||
71 | |||
72 | void forget_cached_acl(struct inode *inode, int type) | ||
73 | { | ||
74 | struct posix_acl **p = acl_by_type(inode, type); | ||
75 | struct posix_acl *old; | ||
76 | spin_lock(&inode->i_lock); | ||
77 | old = *p; | ||
78 | *p = ACL_NOT_CACHED; | ||
79 | spin_unlock(&inode->i_lock); | ||
80 | if (old != ACL_NOT_CACHED) | ||
81 | posix_acl_release(old); | ||
82 | } | ||
83 | EXPORT_SYMBOL(forget_cached_acl); | ||
84 | |||
85 | void forget_all_cached_acls(struct inode *inode) | ||
86 | { | ||
87 | struct posix_acl *old_access, *old_default; | ||
88 | spin_lock(&inode->i_lock); | ||
89 | old_access = inode->i_acl; | ||
90 | old_default = inode->i_default_acl; | ||
91 | inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; | ||
92 | spin_unlock(&inode->i_lock); | ||
93 | if (old_access != ACL_NOT_CACHED) | ||
94 | posix_acl_release(old_access); | ||
95 | if (old_default != ACL_NOT_CACHED) | ||
96 | posix_acl_release(old_default); | ||
97 | } | ||
98 | EXPORT_SYMBOL(forget_all_cached_acls); | ||
30 | 99 | ||
31 | /* | 100 | /* |
32 | * Init a fresh posix_acl | 101 | * Init a fresh posix_acl |
@@ -37,6 +106,7 @@ posix_acl_init(struct posix_acl *acl, int count) | |||
37 | atomic_set(&acl->a_refcount, 1); | 106 | atomic_set(&acl->a_refcount, 1); |
38 | acl->a_count = count; | 107 | acl->a_count = count; |
39 | } | 108 | } |
109 | EXPORT_SYMBOL(posix_acl_init); | ||
40 | 110 | ||
41 | /* | 111 | /* |
42 | * Allocate a new ACL with the specified number of entries. | 112 | * Allocate a new ACL with the specified number of entries. |
@@ -51,6 +121,7 @@ posix_acl_alloc(int count, gfp_t flags) | |||
51 | posix_acl_init(acl, count); | 121 | posix_acl_init(acl, count); |
52 | return acl; | 122 | return acl; |
53 | } | 123 | } |
124 | EXPORT_SYMBOL(posix_acl_alloc); | ||
54 | 125 | ||
55 | /* | 126 | /* |
56 | * Clone an ACL. | 127 | * Clone an ACL. |
@@ -146,6 +217,7 @@ posix_acl_valid(const struct posix_acl *acl) | |||
146 | return 0; | 217 | return 0; |
147 | return -EINVAL; | 218 | return -EINVAL; |
148 | } | 219 | } |
220 | EXPORT_SYMBOL(posix_acl_valid); | ||
149 | 221 | ||
150 | /* | 222 | /* |
151 | * Returns 0 if the acl can be exactly represented in the traditional | 223 | * Returns 0 if the acl can be exactly represented in the traditional |
@@ -186,6 +258,7 @@ posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p) | |||
186 | *mode_p = (*mode_p & ~S_IRWXUGO) | mode; | 258 | *mode_p = (*mode_p & ~S_IRWXUGO) | mode; |
187 | return not_equiv; | 259 | return not_equiv; |
188 | } | 260 | } |
261 | EXPORT_SYMBOL(posix_acl_equiv_mode); | ||
189 | 262 | ||
190 | /* | 263 | /* |
191 | * Create an ACL representing the file mode permission bits of an inode. | 264 | * Create an ACL representing the file mode permission bits of an inode. |
@@ -207,6 +280,7 @@ posix_acl_from_mode(umode_t mode, gfp_t flags) | |||
207 | acl->a_entries[2].e_perm = (mode & S_IRWXO); | 280 | acl->a_entries[2].e_perm = (mode & S_IRWXO); |
208 | return acl; | 281 | return acl; |
209 | } | 282 | } |
283 | EXPORT_SYMBOL(posix_acl_from_mode); | ||
210 | 284 | ||
211 | /* | 285 | /* |
212 | * Return 0 if current is granted want access to the inode | 286 | * Return 0 if current is granted want access to the inode |
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 7931efe71175..fb616942e4c7 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h | |||
@@ -94,78 +94,12 @@ extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); | |||
94 | extern struct posix_acl *get_posix_acl(struct inode *, int); | 94 | extern struct posix_acl *get_posix_acl(struct inode *, int); |
95 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); | 95 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); |
96 | 96 | ||
97 | #ifdef CONFIG_FS_POSIX_ACL | 97 | struct posix_acl **acl_by_type(struct inode *inode, int type); |
98 | static inline struct posix_acl **acl_by_type(struct inode *inode, int type) | 98 | struct posix_acl *get_cached_acl(struct inode *inode, int type); |
99 | { | 99 | struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type); |
100 | switch (type) { | 100 | void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl); |
101 | case ACL_TYPE_ACCESS: | 101 | void forget_cached_acl(struct inode *inode, int type); |
102 | return &inode->i_acl; | 102 | void forget_all_cached_acls(struct inode *inode); |
103 | case ACL_TYPE_DEFAULT: | ||
104 | return &inode->i_default_acl; | ||
105 | default: | ||
106 | BUG(); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static inline struct posix_acl *get_cached_acl(struct inode *inode, int type) | ||
111 | { | ||
112 | struct posix_acl **p = acl_by_type(inode, type); | ||
113 | struct posix_acl *acl = ACCESS_ONCE(*p); | ||
114 | if (acl) { | ||
115 | spin_lock(&inode->i_lock); | ||
116 | acl = *p; | ||
117 | if (acl != ACL_NOT_CACHED) | ||
118 | acl = posix_acl_dup(acl); | ||
119 | spin_unlock(&inode->i_lock); | ||
120 | } | ||
121 | return acl; | ||
122 | } | ||
123 | |||
124 | static inline struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) | ||
125 | { | ||
126 | return rcu_dereference(*acl_by_type(inode, type)); | ||
127 | } | ||
128 | |||
129 | static inline void set_cached_acl(struct inode *inode, | ||
130 | int type, | ||
131 | struct posix_acl *acl) | ||
132 | { | ||
133 | struct posix_acl **p = acl_by_type(inode, type); | ||
134 | struct posix_acl *old; | ||
135 | spin_lock(&inode->i_lock); | ||
136 | old = *p; | ||
137 | rcu_assign_pointer(*p, posix_acl_dup(acl)); | ||
138 | spin_unlock(&inode->i_lock); | ||
139 | if (old != ACL_NOT_CACHED) | ||
140 | posix_acl_release(old); | ||
141 | } | ||
142 | |||
143 | static inline void forget_cached_acl(struct inode *inode, int type) | ||
144 | { | ||
145 | struct posix_acl **p = acl_by_type(inode, type); | ||
146 | struct posix_acl *old; | ||
147 | spin_lock(&inode->i_lock); | ||
148 | old = *p; | ||
149 | *p = ACL_NOT_CACHED; | ||
150 | spin_unlock(&inode->i_lock); | ||
151 | if (old != ACL_NOT_CACHED) | ||
152 | posix_acl_release(old); | ||
153 | } | ||
154 | |||
155 | static inline void forget_all_cached_acls(struct inode *inode) | ||
156 | { | ||
157 | struct posix_acl *old_access, *old_default; | ||
158 | spin_lock(&inode->i_lock); | ||
159 | old_access = inode->i_acl; | ||
160 | old_default = inode->i_default_acl; | ||
161 | inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; | ||
162 | spin_unlock(&inode->i_lock); | ||
163 | if (old_access != ACL_NOT_CACHED) | ||
164 | posix_acl_release(old_access); | ||
165 | if (old_default != ACL_NOT_CACHED) | ||
166 | posix_acl_release(old_default); | ||
167 | } | ||
168 | #endif | ||
169 | 103 | ||
170 | static inline void cache_no_acl(struct inode *inode) | 104 | static inline void cache_no_acl(struct inode *inode) |
171 | { | 105 | { |