aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/acl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 15:53:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 15:53:15 -0400
commit0003230e8200699860f0b10af524dc47bf8aecad (patch)
tree8addb0c889b32111d6973c46cd3d0a5b5c17606c /fs/ext4/acl.c
parent4b478cedcdc1b2d131170f22bd3f916e53472f52 (diff)
parent4e34e719e457f2e031297175410fc0bd4016a085 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: fs: take the ACL checks to common code bury posix_acl_..._masq() variants kill boilerplates around posix_acl_create_masq() generic_acl: no need to clone acl just to push it to set_cached_acl() kill boilerplate around posix_acl_chmod_masq() reiserfs: cache negative ACLs for v1 stat format xfs: cache negative ACLs if there is no attribute fork 9p: do no return 0 from ->check_acl without actually checking vfs: move ACL cache lookup into generic code CIFS: Fix oops while mounting with prefixpath xfs: Fix wrong return value of xfs_file_aio_write fix devtmpfs race caam: don't pass bogus S_IFCHR to debugfs_create_...() get rid of create_proc_entry() abuses - proc_mkdir() is there for purpose asus-wmi: ->is_visible() can't return negative fix jffs2 ACLs on big-endian with 16bit mode_t 9p: close ACL leaks ocfs2_init_acl(): fix a leak VFS : mount lock scalability for internal mounts
Diffstat (limited to 'fs/ext4/acl.c')
-rw-r--r--fs/ext4/acl.c95
1 files changed, 30 insertions, 65 deletions
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 60d900fcc3db..dca2d1ded931 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/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 *
135ext4_get_acl(struct inode *inode, int type) 135ext4_get_acl(struct inode *inode, int type)
136{ 136{
137 int name_index; 137 int name_index;
@@ -237,29 +237,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
237 return error; 237 return error;
238} 238}
239 239
240int
241ext4_check_acl(struct inode *inode, int mask)
242{
243 struct posix_acl *acl;
244
245 if (mask & MAY_NOT_BLOCK) {
246 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
247 return -ECHILD;
248 return -EAGAIN;
249 }
250
251 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
252 if (IS_ERR(acl))
253 return PTR_ERR(acl);
254 if (acl) {
255 int error = posix_acl_permission(inode, acl, mask);
256 posix_acl_release(acl);
257 return error;
258 }
259
260 return -EAGAIN;
261}
262
263/* 240/*
264 * Initialize the ACLs of a new inode. Called from ext4_new_inode. 241 * Initialize the ACLs of a new inode. Called from ext4_new_inode.
265 * 242 *
@@ -282,8 +259,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
282 inode->i_mode &= ~current_umask(); 259 inode->i_mode &= ~current_umask();
283 } 260 }
284 if (test_opt(inode->i_sb, POSIX_ACL) && acl) { 261 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
285 struct posix_acl *clone; 262 mode_t mode = inode->i_mode;
286 mode_t mode;
287 263
288 if (S_ISDIR(inode->i_mode)) { 264 if (S_ISDIR(inode->i_mode)) {
289 error = ext4_set_acl(handle, inode, 265 error = ext4_set_acl(handle, inode,
@@ -291,22 +267,15 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
291 if (error) 267 if (error)
292 goto cleanup; 268 goto cleanup;
293 } 269 }
294 clone = posix_acl_clone(acl, GFP_NOFS); 270 error = posix_acl_create(&acl, GFP_NOFS, &mode);
295 error = -ENOMEM; 271 if (error < 0)
296 if (!clone) 272 return error;
297 goto cleanup; 273
298 274 inode->i_mode = mode;
299 mode = inode->i_mode; 275 if (error > 0) {
300 error = posix_acl_create_masq(clone, &mode); 276 /* This is an extended ACL */
301 if (error >= 0) { 277 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
302 inode->i_mode = mode;
303 if (error > 0) {
304 /* This is an extended ACL */
305 error = ext4_set_acl(handle, inode,
306 ACL_TYPE_ACCESS, clone);
307 }
308 } 278 }
309 posix_acl_release(clone);
310 } 279 }
311cleanup: 280cleanup:
312 posix_acl_release(acl); 281 posix_acl_release(acl);
@@ -330,9 +299,12 @@ cleanup:
330int 299int
331ext4_acl_chmod(struct inode *inode) 300ext4_acl_chmod(struct inode *inode)
332{ 301{
333 struct posix_acl *acl, *clone; 302 struct posix_acl *acl;
303 handle_t *handle;
304 int retries = 0;
334 int error; 305 int error;
335 306
307
336 if (S_ISLNK(inode->i_mode)) 308 if (S_ISLNK(inode->i_mode))
337 return -EOPNOTSUPP; 309 return -EOPNOTSUPP;
338 if (!test_opt(inode->i_sb, POSIX_ACL)) 310 if (!test_opt(inode->i_sb, POSIX_ACL))
@@ -340,31 +312,24 @@ ext4_acl_chmod(struct inode *inode)
340 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); 312 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
341 if (IS_ERR(acl) || !acl) 313 if (IS_ERR(acl) || !acl)
342 return PTR_ERR(acl); 314 return PTR_ERR(acl);
343 clone = posix_acl_clone(acl, GFP_KERNEL); 315 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
344 posix_acl_release(acl); 316 if (error)
345 if (!clone) 317 return error;
346 return -ENOMEM; 318retry:
347 error = posix_acl_chmod_masq(clone, inode->i_mode); 319 handle = ext4_journal_start(inode,
348 if (!error) { 320 EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
349 handle_t *handle; 321 if (IS_ERR(handle)) {
350 int retries = 0; 322 error = PTR_ERR(handle);
351 323 ext4_std_error(inode->i_sb, error);
352 retry: 324 goto out;
353 handle = ext4_journal_start(inode,
354 EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
355 if (IS_ERR(handle)) {
356 error = PTR_ERR(handle);
357 ext4_std_error(inode->i_sb, error);
358 goto out;
359 }
360 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
361 ext4_journal_stop(handle);
362 if (error == -ENOSPC &&
363 ext4_should_retry_alloc(inode->i_sb, &retries))
364 goto retry;
365 } 325 }
326 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
327 ext4_journal_stop(handle);
328 if (error == -ENOSPC &&
329 ext4_should_retry_alloc(inode->i_sb, &retries))
330 goto retry;
366out: 331out:
367 posix_acl_release(clone); 332 posix_acl_release(acl);
368 return error; 333 return error;
369} 334}
370 335