diff options
Diffstat (limited to 'fs/gfs2/acl.c')
-rw-r--r-- | fs/gfs2/acl.c | 104 |
1 files changed, 45 insertions, 59 deletions
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index fa881bdc3d85..f6777f167260 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include "gfs2.h" | 19 | #include "gfs2.h" |
20 | #include "incore.h" | 20 | #include "incore.h" |
21 | #include "acl.h" | 21 | #include "acl.h" |
22 | #include "eaops.h" | ||
23 | #include "eattr.h" | 22 | #include "eattr.h" |
24 | #include "glock.h" | 23 | #include "glock.h" |
25 | #include "inode.h" | 24 | #include "inode.h" |
@@ -31,8 +30,7 @@ | |||
31 | #define ACL_DEFAULT 0 | 30 | #define ACL_DEFAULT 0 |
32 | 31 | ||
33 | int gfs2_acl_validate_set(struct gfs2_inode *ip, int access, | 32 | int gfs2_acl_validate_set(struct gfs2_inode *ip, int access, |
34 | struct gfs2_ea_request *er, | 33 | struct gfs2_ea_request *er, int *remove, mode_t *mode) |
35 | int *remove, mode_t *mode) | ||
36 | { | 34 | { |
37 | struct posix_acl *acl; | 35 | struct posix_acl *acl; |
38 | int error; | 36 | int error; |
@@ -83,30 +81,20 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access) | |||
83 | return 0; | 81 | return 0; |
84 | } | 82 | } |
85 | 83 | ||
86 | static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl, | 84 | static int acl_get(struct gfs2_inode *ip, const char *name, |
87 | struct gfs2_ea_location *el, char **data, unsigned int *len) | 85 | struct posix_acl **acl, struct gfs2_ea_location *el, |
86 | char **datap, unsigned int *lenp) | ||
88 | { | 87 | { |
89 | struct gfs2_ea_request er; | 88 | char *data; |
90 | struct gfs2_ea_location el_this; | 89 | unsigned int len; |
91 | int error; | 90 | int error; |
92 | 91 | ||
92 | el->el_bh = NULL; | ||
93 | |||
93 | if (!ip->i_eattr) | 94 | if (!ip->i_eattr) |
94 | return 0; | 95 | return 0; |
95 | 96 | ||
96 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 97 | error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, el); |
97 | if (access) { | ||
98 | er.er_name = GFS2_POSIX_ACL_ACCESS; | ||
99 | er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN; | ||
100 | } else { | ||
101 | er.er_name = GFS2_POSIX_ACL_DEFAULT; | ||
102 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; | ||
103 | } | ||
104 | er.er_type = GFS2_EATYPE_SYS; | ||
105 | |||
106 | if (!el) | ||
107 | el = &el_this; | ||
108 | |||
109 | error = gfs2_ea_find(ip, &er, el); | ||
110 | if (error) | 98 | if (error) |
111 | return error; | 99 | return error; |
112 | if (!el->el_ea) | 100 | if (!el->el_ea) |
@@ -114,32 +102,31 @@ static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl, | |||
114 | if (!GFS2_EA_DATA_LEN(el->el_ea)) | 102 | if (!GFS2_EA_DATA_LEN(el->el_ea)) |
115 | goto out; | 103 | goto out; |
116 | 104 | ||
117 | er.er_data_len = GFS2_EA_DATA_LEN(el->el_ea); | 105 | len = GFS2_EA_DATA_LEN(el->el_ea); |
118 | er.er_data = kmalloc(er.er_data_len, GFP_NOFS); | 106 | data = kmalloc(len, GFP_NOFS); |
119 | error = -ENOMEM; | 107 | error = -ENOMEM; |
120 | if (!er.er_data) | 108 | if (!data) |
121 | goto out; | 109 | goto out; |
122 | 110 | ||
123 | error = gfs2_ea_get_copy(ip, el, er.er_data); | 111 | error = gfs2_ea_get_copy(ip, el, data, len); |
124 | if (error) | 112 | if (error < 0) |
125 | goto out_kfree; | 113 | goto out_kfree; |
114 | error = 0; | ||
126 | 115 | ||
127 | if (acl) { | 116 | if (acl) { |
128 | *acl = posix_acl_from_xattr(er.er_data, er.er_data_len); | 117 | *acl = posix_acl_from_xattr(data, len); |
129 | if (IS_ERR(*acl)) | 118 | if (IS_ERR(*acl)) |
130 | error = PTR_ERR(*acl); | 119 | error = PTR_ERR(*acl); |
131 | } | 120 | } |
132 | 121 | ||
133 | out_kfree: | 122 | out_kfree: |
134 | if (error || !data) | 123 | if (error || !datap) { |
135 | kfree(er.er_data); | 124 | kfree(data); |
136 | else { | 125 | } else { |
137 | *data = er.er_data; | 126 | *datap = data; |
138 | *len = er.er_data_len; | 127 | *lenp = len; |
139 | } | 128 | } |
140 | out: | 129 | out: |
141 | if (error || el == &el_this) | ||
142 | brelse(el->el_bh); | ||
143 | return error; | 130 | return error; |
144 | } | 131 | } |
145 | 132 | ||
@@ -153,10 +140,12 @@ out: | |||
153 | 140 | ||
154 | int gfs2_check_acl(struct inode *inode, int mask) | 141 | int gfs2_check_acl(struct inode *inode, int mask) |
155 | { | 142 | { |
143 | struct gfs2_ea_location el; | ||
156 | struct posix_acl *acl = NULL; | 144 | struct posix_acl *acl = NULL; |
157 | int error; | 145 | int error; |
158 | 146 | ||
159 | error = acl_get(GFS2_I(inode), ACL_ACCESS, &acl, NULL, NULL, NULL); | 147 | error = acl_get(GFS2_I(inode), GFS2_POSIX_ACL_ACCESS, &acl, &el, NULL, NULL); |
148 | brelse(el.el_bh); | ||
160 | if (error) | 149 | if (error) |
161 | return error; | 150 | return error; |
162 | 151 | ||
@@ -196,10 +185,12 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode) | |||
196 | 185 | ||
197 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | 186 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) |
198 | { | 187 | { |
188 | struct gfs2_ea_location el; | ||
199 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 189 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
200 | struct posix_acl *acl = NULL, *clone; | 190 | struct posix_acl *acl = NULL, *clone; |
201 | struct gfs2_ea_request er; | ||
202 | mode_t mode = ip->i_inode.i_mode; | 191 | mode_t mode = ip->i_inode.i_mode; |
192 | char *data = NULL; | ||
193 | unsigned int len; | ||
203 | int error; | 194 | int error; |
204 | 195 | ||
205 | if (!sdp->sd_args.ar_posix_acl) | 196 | if (!sdp->sd_args.ar_posix_acl) |
@@ -207,11 +198,8 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
207 | if (S_ISLNK(ip->i_inode.i_mode)) | 198 | if (S_ISLNK(ip->i_inode.i_mode)) |
208 | return 0; | 199 | return 0; |
209 | 200 | ||
210 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 201 | error = acl_get(dip, GFS2_POSIX_ACL_DEFAULT, &acl, &el, &data, &len); |
211 | er.er_type = GFS2_EATYPE_SYS; | 202 | brelse(el.el_bh); |
212 | |||
213 | error = acl_get(dip, ACL_DEFAULT, &acl, NULL, | ||
214 | &er.er_data, &er.er_data_len); | ||
215 | if (error) | 203 | if (error) |
216 | return error; | 204 | return error; |
217 | if (!acl) { | 205 | if (!acl) { |
@@ -229,9 +217,8 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
229 | acl = clone; | 217 | acl = clone; |
230 | 218 | ||
231 | if (S_ISDIR(ip->i_inode.i_mode)) { | 219 | if (S_ISDIR(ip->i_inode.i_mode)) { |
232 | er.er_name = GFS2_POSIX_ACL_DEFAULT; | 220 | error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS, |
233 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; | 221 | GFS2_POSIX_ACL_DEFAULT, data, len, 0); |
234 | error = gfs2_system_eaops.eo_set(ip, &er); | ||
235 | if (error) | 222 | if (error) |
236 | goto out; | 223 | goto out; |
237 | } | 224 | } |
@@ -239,21 +226,19 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
239 | error = posix_acl_create_masq(acl, &mode); | 226 | error = posix_acl_create_masq(acl, &mode); |
240 | if (error < 0) | 227 | if (error < 0) |
241 | goto out; | 228 | goto out; |
242 | if (error > 0) { | 229 | if (error == 0) |
243 | er.er_name = GFS2_POSIX_ACL_ACCESS; | 230 | goto munge; |
244 | er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN; | ||
245 | posix_acl_to_xattr(acl, er.er_data, er.er_data_len); | ||
246 | er.er_mode = mode; | ||
247 | er.er_flags = GFS2_ERF_MODE; | ||
248 | error = gfs2_system_eaops.eo_set(ip, &er); | ||
249 | if (error) | ||
250 | goto out; | ||
251 | } else | ||
252 | munge_mode(ip, mode); | ||
253 | 231 | ||
232 | posix_acl_to_xattr(acl, data, len); | ||
233 | error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS, | ||
234 | GFS2_POSIX_ACL_ACCESS, data, len, 0); | ||
235 | if (error) | ||
236 | goto out; | ||
237 | munge: | ||
238 | error = munge_mode(ip, mode); | ||
254 | out: | 239 | out: |
255 | posix_acl_release(acl); | 240 | posix_acl_release(acl); |
256 | kfree(er.er_data); | 241 | kfree(data); |
257 | return error; | 242 | return error; |
258 | } | 243 | } |
259 | 244 | ||
@@ -265,9 +250,9 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | |||
265 | unsigned int len; | 250 | unsigned int len; |
266 | int error; | 251 | int error; |
267 | 252 | ||
268 | error = acl_get(ip, ACL_ACCESS, &acl, &el, &data, &len); | 253 | error = acl_get(ip, GFS2_POSIX_ACL_ACCESS, &acl, &el, &data, &len); |
269 | if (error) | 254 | if (error) |
270 | return error; | 255 | goto out_brelse; |
271 | if (!acl) | 256 | if (!acl) |
272 | return gfs2_setattr_simple(ip, attr); | 257 | return gfs2_setattr_simple(ip, attr); |
273 | 258 | ||
@@ -286,8 +271,9 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | |||
286 | 271 | ||
287 | out: | 272 | out: |
288 | posix_acl_release(acl); | 273 | posix_acl_release(acl); |
289 | brelse(el.el_bh); | ||
290 | kfree(data); | 274 | kfree(data); |
275 | out_brelse: | ||
276 | brelse(el.el_bh); | ||
291 | return error; | 277 | return error; |
292 | } | 278 | } |
293 | 279 | ||