aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/reiserfs/inode.c3
-rw-r--r--fs/reiserfs/namei.c14
-rw-r--r--fs/reiserfs/xattr.c39
-rw-r--r--fs/reiserfs/xattr_acl.c105
4 files changed, 115 insertions, 46 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 50a73e7afdc8..995f6975cae1 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1914,9 +1914,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
1914 goto out_inserted_sd; 1914 goto out_inserted_sd;
1915 } 1915 }
1916 1916
1917 /* XXX CHECK THIS */
1918 if (reiserfs_posixacl(inode->i_sb)) { 1917 if (reiserfs_posixacl(inode->i_sb)) {
1919 retval = reiserfs_inherit_default_acl(dir, dentry, inode); 1918 retval = reiserfs_inherit_default_acl(th, dir, dentry, inode);
1920 if (retval) { 1919 if (retval) {
1921 err = retval; 1920 err = retval;
1922 reiserfs_check_path(&path_to_key); 1921 reiserfs_check_path(&path_to_key);
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index ddf1bcd41c87..d9c1c8bd2950 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -598,15 +598,13 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode,
598 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + 598 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
599 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); 599 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
600 struct reiserfs_transaction_handle th; 600 struct reiserfs_transaction_handle th;
601 int locked;
602 601
603 if (!(inode = new_inode(dir->i_sb))) { 602 if (!(inode = new_inode(dir->i_sb))) {
604 return -ENOMEM; 603 return -ENOMEM;
605 } 604 }
606 new_inode_init(inode, dir, mode); 605 new_inode_init(inode, dir, mode);
607 606
608 locked = reiserfs_cache_default_acl(dir); 607 jbegin_count += reiserfs_cache_default_acl(dir);
609
610 reiserfs_write_lock(dir->i_sb); 608 reiserfs_write_lock(dir->i_sb);
611 609
612 retval = journal_begin(&th, dir->i_sb, jbegin_count); 610 retval = journal_begin(&th, dir->i_sb, jbegin_count);
@@ -662,7 +660,6 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
662 JOURNAL_PER_BALANCE_CNT * 3 + 660 JOURNAL_PER_BALANCE_CNT * 3 +
663 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + 661 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
664 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); 662 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
665 int locked;
666 663
667 if (!new_valid_dev(rdev)) 664 if (!new_valid_dev(rdev))
668 return -EINVAL; 665 return -EINVAL;
@@ -672,8 +669,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
672 } 669 }
673 new_inode_init(inode, dir, mode); 670 new_inode_init(inode, dir, mode);
674 671
675 locked = reiserfs_cache_default_acl(dir); 672 jbegin_count += reiserfs_cache_default_acl(dir);
676
677 reiserfs_write_lock(dir->i_sb); 673 reiserfs_write_lock(dir->i_sb);
678 674
679 retval = journal_begin(&th, dir->i_sb, jbegin_count); 675 retval = journal_begin(&th, dir->i_sb, jbegin_count);
@@ -732,7 +728,6 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
732 JOURNAL_PER_BALANCE_CNT * 3 + 728 JOURNAL_PER_BALANCE_CNT * 3 +
733 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + 729 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
734 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); 730 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
735 int locked;
736 731
737#ifdef DISPLACE_NEW_PACKING_LOCALITIES 732#ifdef DISPLACE_NEW_PACKING_LOCALITIES
738 /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ 733 /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */
@@ -744,8 +739,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
744 } 739 }
745 new_inode_init(inode, dir, mode); 740 new_inode_init(inode, dir, mode);
746 741
747 locked = reiserfs_cache_default_acl(dir); 742 jbegin_count += reiserfs_cache_default_acl(dir);
748
749 reiserfs_write_lock(dir->i_sb); 743 reiserfs_write_lock(dir->i_sb);
750 744
751 retval = journal_begin(&th, dir->i_sb, jbegin_count); 745 retval = journal_begin(&th, dir->i_sb, jbegin_count);
@@ -1034,8 +1028,6 @@ static int reiserfs_symlink(struct inode *parent_dir,
1034 memcpy(name, symname, strlen(symname)); 1028 memcpy(name, symname, strlen(symname));
1035 padd_item(name, item_len, strlen(symname)); 1029 padd_item(name, item_len, strlen(symname));
1036 1030
1037 /* We would inherit the default ACL here, but symlinks don't get ACLs */
1038
1039 retval = journal_begin(&th, parent_dir->i_sb, jbegin_count); 1031 retval = journal_begin(&th, parent_dir->i_sb, jbegin_count);
1040 if (retval) { 1032 if (retval) {
1041 drop_new_inode(inode); 1033 drop_new_inode(inode);
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d3ce27436605..c2e3a92aaf2b 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -632,8 +632,9 @@ out_dput:
632 * inode->i_mutex: down 632 * inode->i_mutex: down
633 */ 633 */
634int 634int
635__reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, 635reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
636 size_t buffer_size, int flags) 636 struct inode *inode, const char *name,
637 const void *buffer, size_t buffer_size, int flags)
637{ 638{
638 int err = 0; 639 int err = 0;
639 struct dentry *dentry; 640 struct dentry *dentry;
@@ -723,14 +724,34 @@ out_unlock:
723 return err; 724 return err;
724} 725}
725 726
726int 727/* We need to start a transaction to maintain lock ordering */
727reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, 728int reiserfs_xattr_set(struct inode *inode, const char *name,
728 size_t buffer_size, int flags) 729 const void *buffer, size_t buffer_size, int flags)
729{ 730{
730 int err = __reiserfs_xattr_set(inode, name, buffer, buffer_size, flags); 731
731 if (err == -ENODATA) 732 struct reiserfs_transaction_handle th;
732 err = 0; 733 int error, error2;
733 return err; 734 size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size);
735
736 if (!(flags & XATTR_REPLACE))
737 jbegin_count += reiserfs_xattr_jcreate_nblocks(inode);
738
739 reiserfs_write_lock(inode->i_sb);
740 error = journal_begin(&th, inode->i_sb, jbegin_count);
741 if (error) {
742 reiserfs_write_unlock(inode->i_sb);
743 return error;
744 }
745
746 error = reiserfs_xattr_set_handle(&th, inode, name,
747 buffer, buffer_size, flags);
748
749 error2 = journal_end(&th, inode->i_sb, jbegin_count);
750 if (error == 0)
751 error = error2;
752 reiserfs_write_unlock(inode->i_sb);
753
754 return error;
734} 755}
735 756
736/* 757/*
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index bfecf7553002..d423416d93d1 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -10,15 +10,17 @@
10#include <linux/reiserfs_acl.h> 10#include <linux/reiserfs_acl.h>
11#include <asm/uaccess.h> 11#include <asm/uaccess.h>
12 12
13static int reiserfs_set_acl(struct inode *inode, int type, 13static int reiserfs_set_acl(struct reiserfs_transaction_handle *th,
14 struct inode *inode, int type,
14 struct posix_acl *acl); 15 struct posix_acl *acl);
15 16
16static int 17static int
17xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) 18xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
18{ 19{
19 struct posix_acl *acl; 20 struct posix_acl *acl;
20 int error; 21 int error, error2;
21 22 struct reiserfs_transaction_handle th;
23 size_t jcreate_blocks;
22 if (!reiserfs_posixacl(inode->i_sb)) 24 if (!reiserfs_posixacl(inode->i_sb))
23 return -EOPNOTSUPP; 25 return -EOPNOTSUPP;
24 if (!is_owner_or_cap(inode)) 26 if (!is_owner_or_cap(inode))
@@ -36,7 +38,21 @@ xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
36 } else 38 } else
37 acl = NULL; 39 acl = NULL;
38 40
39 error = reiserfs_set_acl(inode, type, acl); 41 /* Pessimism: We can't assume that anything from the xattr root up
42 * has been created. */
43
44 jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) +
45 reiserfs_xattr_nblocks(inode, size) * 2;
46
47 reiserfs_write_lock(inode->i_sb);
48 error = journal_begin(&th, inode->i_sb, jcreate_blocks);
49 if (error == 0) {
50 error = reiserfs_set_acl(&th, inode, type, acl);
51 error2 = journal_end(&th, inode->i_sb, jcreate_blocks);
52 if (error2)
53 error = error2;
54 }
55 reiserfs_write_unlock(inode->i_sb);
40 56
41 release_and_out: 57 release_and_out:
42 posix_acl_release(acl); 58 posix_acl_release(acl);
@@ -266,7 +282,8 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
266 * BKL held [before 2.5.x] 282 * BKL held [before 2.5.x]
267 */ 283 */
268static int 284static int
269reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) 285reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
286 int type, struct posix_acl *acl)
270{ 287{
271 char *name; 288 char *name;
272 void *value = NULL; 289 void *value = NULL;
@@ -310,7 +327,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
310 return (int)PTR_ERR(value); 327 return (int)PTR_ERR(value);
311 } 328 }
312 329
313 error = __reiserfs_xattr_set(inode, name, value, size, 0); 330 error = reiserfs_xattr_set_handle(th, inode, name, value, size, 0);
314 331
315 /* 332 /*
316 * Ensure that the inode gets dirtied if we're only using 333 * Ensure that the inode gets dirtied if we're only using
@@ -337,7 +354,8 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
337/* dir->i_mutex: locked, 354/* dir->i_mutex: locked,
338 * inode is new and not released into the wild yet */ 355 * inode is new and not released into the wild yet */
339int 356int
340reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, 357reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
358 struct inode *dir, struct dentry *dentry,
341 struct inode *inode) 359 struct inode *inode)
342{ 360{
343 struct posix_acl *acl; 361 struct posix_acl *acl;
@@ -374,7 +392,8 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
374 392
375 /* Copy the default ACL to the default ACL of a new directory */ 393 /* Copy the default ACL to the default ACL of a new directory */
376 if (S_ISDIR(inode->i_mode)) { 394 if (S_ISDIR(inode->i_mode)) {
377 err = reiserfs_set_acl(inode, ACL_TYPE_DEFAULT, acl); 395 err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT,
396 acl);
378 if (err) 397 if (err)
379 goto cleanup; 398 goto cleanup;
380 } 399 }
@@ -395,9 +414,9 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
395 414
396 /* If we need an ACL.. */ 415 /* If we need an ACL.. */
397 if (need_acl > 0) { 416 if (need_acl > 0) {
398 err = 417 err = reiserfs_set_acl(th, inode,
399 reiserfs_set_acl(inode, ACL_TYPE_ACCESS, 418 ACL_TYPE_ACCESS,
400 acl_copy); 419 acl_copy);
401 if (err) 420 if (err)
402 goto cleanup_copy; 421 goto cleanup_copy;
403 } 422 }
@@ -415,21 +434,45 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
415 return err; 434 return err;
416} 435}
417 436
418/* Looks up and caches the result of the default ACL. 437/* This is used to cache the default acl before a new object is created.
419 * We do this so that we don't need to carry the xattr_sem into 438 * The biggest reason for this is to get an idea of how many blocks will
420 * reiserfs_new_inode if we don't need to */ 439 * actually be required for the create operation if we must inherit an ACL.
440 * An ACL write can add up to 3 object creations and an additional file write
441 * so we'd prefer not to reserve that many blocks in the journal if we can.
442 * It also has the advantage of not loading the ACL with a transaction open,
443 * this may seem silly, but if the owner of the directory is doing the
444 * creation, the ACL may not be loaded since the permissions wouldn't require
445 * it.
446 * We return the number of blocks required for the transaction.
447 */
421int reiserfs_cache_default_acl(struct inode *inode) 448int reiserfs_cache_default_acl(struct inode *inode)
422{ 449{
423 int ret = 0; 450 struct posix_acl *acl;
424 if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) { 451 int nblocks = 0;
425 struct posix_acl *acl; 452
426 acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); 453 if (IS_PRIVATE(inode))
427 ret = (acl && !IS_ERR(acl)); 454 return 0;
428 if (ret) 455
429 posix_acl_release(acl); 456 acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
457
458 if (acl && !IS_ERR(acl)) {
459 int size = reiserfs_acl_size(acl->a_count);
460
461 /* Other xattrs can be created during inode creation. We don't
462 * want to claim too many blocks, so we check to see if we
463 * we need to create the tree to the xattrs, and then we
464 * just want two files. */
465 nblocks = reiserfs_xattr_jcreate_nblocks(inode);
466 nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
467
468 REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
469
470 /* We need to account for writes + bitmaps for two files */
471 nblocks += reiserfs_xattr_nblocks(inode, size) * 4;
472 posix_acl_release(acl);
430 } 473 }
431 474
432 return ret; 475 return nblocks;
433} 476}
434 477
435int reiserfs_acl_chmod(struct inode *inode) 478int reiserfs_acl_chmod(struct inode *inode)
@@ -455,8 +498,22 @@ int reiserfs_acl_chmod(struct inode *inode)
455 if (!clone) 498 if (!clone)
456 return -ENOMEM; 499 return -ENOMEM;
457 error = posix_acl_chmod_masq(clone, inode->i_mode); 500 error = posix_acl_chmod_masq(clone, inode->i_mode);
458 if (!error) 501 if (!error) {
459 error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); 502 struct reiserfs_transaction_handle th;
503 size_t size = reiserfs_xattr_nblocks(inode,
504 reiserfs_acl_size(clone->a_count));
505 reiserfs_write_lock(inode->i_sb);
506 error = journal_begin(&th, inode->i_sb, size * 2);
507 if (!error) {
508 int error2;
509 error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS,
510 clone);
511 error2 = journal_end(&th, inode->i_sb, size * 2);
512 if (error2)
513 error = error2;
514 }
515 reiserfs_write_unlock(inode->i_sb);
516 }
460 posix_acl_release(clone); 517 posix_acl_release(clone);
461 return error; 518 return error;
462} 519}