aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3/acl.c')
-rw-r--r--fs/ext3/acl.c94
1 files changed, 29 insertions, 65 deletions
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index edfeb293d4cb..6c29bf0df04a 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -131,7 +131,7 @@ fail:
131 * 131 *
132 * inode->i_mutex: don't care 132 * inode->i_mutex: don't care
133 */ 133 */
134static struct posix_acl * 134struct posix_acl *
135ext3_get_acl(struct inode *inode, int type) 135ext3_get_acl(struct inode *inode, int type)
136{ 136{
137 int name_index; 137 int name_index;
@@ -239,29 +239,6 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
239 return error; 239 return error;
240} 240}
241 241
242int
243ext3_check_acl(struct inode *inode, int mask)
244{
245 struct posix_acl *acl;
246
247 if (mask & MAY_NOT_BLOCK) {
248 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
249 return -ECHILD;
250 return -EAGAIN;
251 }
252
253 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
254 if (IS_ERR(acl))
255 return PTR_ERR(acl);
256 if (acl) {
257 int error = posix_acl_permission(inode, acl, mask);
258 posix_acl_release(acl);
259 return error;
260 }
261
262 return -EAGAIN;
263}
264
265/* 242/*
266 * Initialize the ACLs of a new inode. Called from ext3_new_inode. 243 * Initialize the ACLs of a new inode. Called from ext3_new_inode.
267 * 244 *
@@ -284,8 +261,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
284 inode->i_mode &= ~current_umask(); 261 inode->i_mode &= ~current_umask();
285 } 262 }
286 if (test_opt(inode->i_sb, POSIX_ACL) && acl) { 263 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
287 struct posix_acl *clone; 264 mode_t mode = inode->i_mode;
288 mode_t mode;
289 265
290 if (S_ISDIR(inode->i_mode)) { 266 if (S_ISDIR(inode->i_mode)) {
291 error = ext3_set_acl(handle, inode, 267 error = ext3_set_acl(handle, inode,
@@ -293,22 +269,15 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
293 if (error) 269 if (error)
294 goto cleanup; 270 goto cleanup;
295 } 271 }
296 clone = posix_acl_clone(acl, GFP_NOFS); 272 error = posix_acl_create(&acl, GFP_NOFS, &mode);
297 error = -ENOMEM; 273 if (error < 0)
298 if (!clone) 274 return error;
299 goto cleanup; 275
300 276 inode->i_mode = mode;
301 mode = inode->i_mode; 277 if (error > 0) {
302 error = posix_acl_create_masq(clone, &mode); 278 /* This is an extended ACL */
303 if (error >= 0) { 279 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
304 inode->i_mode = mode;
305 if (error > 0) {
306 /* This is an extended ACL */
307 error = ext3_set_acl(handle, inode,
308 ACL_TYPE_ACCESS, clone);
309 }
310 } 280 }
311 posix_acl_release(clone);
312 } 281 }
313cleanup: 282cleanup:
314 posix_acl_release(acl); 283 posix_acl_release(acl);
@@ -332,7 +301,9 @@ cleanup:
332int 301int
333ext3_acl_chmod(struct inode *inode) 302ext3_acl_chmod(struct inode *inode)
334{ 303{
335 struct posix_acl *acl, *clone; 304 struct posix_acl *acl;
305 handle_t *handle;
306 int retries = 0;
336 int error; 307 int error;
337 308
338 if (S_ISLNK(inode->i_mode)) 309 if (S_ISLNK(inode->i_mode))
@@ -342,31 +313,24 @@ ext3_acl_chmod(struct inode *inode)
342 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); 313 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
343 if (IS_ERR(acl) || !acl) 314 if (IS_ERR(acl) || !acl)
344 return PTR_ERR(acl); 315 return PTR_ERR(acl);
345 clone = posix_acl_clone(acl, GFP_KERNEL); 316 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
346 posix_acl_release(acl); 317 if (error)
347 if (!clone) 318 return error;
348 return -ENOMEM; 319retry:
349 error = posix_acl_chmod_masq(clone, inode->i_mode); 320 handle = ext3_journal_start(inode,
350 if (!error) { 321 EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
351 handle_t *handle; 322 if (IS_ERR(handle)) {
352 int retries = 0; 323 error = PTR_ERR(handle);
353 324 ext3_std_error(inode->i_sb, error);
354 retry: 325 goto out;
355 handle = ext3_journal_start(inode,
356 EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
357 if (IS_ERR(handle)) {
358 error = PTR_ERR(handle);
359 ext3_std_error(inode->i_sb, error);
360 goto out;
361 }
362 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
363 ext3_journal_stop(handle);
364 if (error == -ENOSPC &&
365 ext3_should_retry_alloc(inode->i_sb, &retries))
366 goto retry;
367 } 326 }
327 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
328 ext3_journal_stop(handle);
329 if (error == -ENOSPC &&
330 ext3_should_retry_alloc(inode->i_sb, &retries))
331 goto retry;
368out: 332out:
369 posix_acl_release(clone); 333 posix_acl_release(acl);
370 return error; 334 return error;
371} 335}
372 336