diff options
author | Tiger Yang <tiger.yang@oracle.com> | 2008-12-09 03:42:51 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:40:36 -0500 |
commit | 0e445b6fe93c723fe8093fd04ddfeb11ae2de082 (patch) | |
tree | a7c2d8ccab64ef70477992b0121dd52966c66154 /fs | |
parent | 90cb546cada68bb8c2278afdb4b65c2ac11f2877 (diff) |
ocfs2: calculate and reserve credits for xattr value in mknod
We extend the credits for xattr's large value in set_value_outside
before, this can give rise to a credits issue when we set one security
entry and two acl entries duing mknod. As we remove extend_trans form
set_value_outside, we must calculate and reserve the credits for
xattr's large value in mknod.
Signed-off-by: Tiger Yang <tiger.yang@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/xattr.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 73fb9f762512..e5be470e7504 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -490,9 +490,14 @@ int ocfs2_calc_security_init(struct inode *dir, | |||
490 | } | 490 | } |
491 | 491 | ||
492 | /* reserve clusters for xattr value which will be set in B tree*/ | 492 | /* reserve clusters for xattr value which will be set in B tree*/ |
493 | if (si->value_len > OCFS2_XATTR_INLINE_SIZE) | 493 | if (si->value_len > OCFS2_XATTR_INLINE_SIZE) { |
494 | *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, | 494 | int new_clusters = ocfs2_clusters_for_bytes(dir->i_sb, |
495 | si->value_len); | 495 | si->value_len); |
496 | |||
497 | *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb, | ||
498 | new_clusters); | ||
499 | *want_clusters += new_clusters; | ||
500 | } | ||
496 | return ret; | 501 | return ret; |
497 | } | 502 | } |
498 | 503 | ||
@@ -506,9 +511,7 @@ int ocfs2_calc_xattr_init(struct inode *dir, | |||
506 | { | 511 | { |
507 | int ret = 0; | 512 | int ret = 0; |
508 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 513 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
509 | int s_size = 0; | 514 | int s_size = 0, a_size = 0, acl_len = 0, new_clusters; |
510 | int a_size = 0; | ||
511 | int acl_len = 0; | ||
512 | 515 | ||
513 | if (si->enable) | 516 | if (si->enable) |
514 | s_size = ocfs2_xattr_entry_real_size(strlen(si->name), | 517 | s_size = ocfs2_xattr_entry_real_size(strlen(si->name), |
@@ -556,16 +559,25 @@ int ocfs2_calc_xattr_init(struct inode *dir, | |||
556 | *xattr_credits += ocfs2_blocks_per_xattr_bucket(dir->i_sb); | 559 | *xattr_credits += ocfs2_blocks_per_xattr_bucket(dir->i_sb); |
557 | } | 560 | } |
558 | 561 | ||
559 | /* reserve clusters for xattr value which will be set in B tree*/ | 562 | /* |
560 | if (si->enable && si->value_len > OCFS2_XATTR_INLINE_SIZE) | 563 | * reserve credits and clusters for xattrs which has large value |
561 | *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, | 564 | * and have to be set outside |
562 | si->value_len); | 565 | */ |
566 | if (si->enable && si->value_len > OCFS2_XATTR_INLINE_SIZE) { | ||
567 | new_clusters = ocfs2_clusters_for_bytes(dir->i_sb, | ||
568 | si->value_len); | ||
569 | *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb, | ||
570 | new_clusters); | ||
571 | *want_clusters += new_clusters; | ||
572 | } | ||
563 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL && | 573 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL && |
564 | acl_len > OCFS2_XATTR_INLINE_SIZE) { | 574 | acl_len > OCFS2_XATTR_INLINE_SIZE) { |
565 | *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, acl_len); | 575 | /* for directory, it has DEFAULT and ACCESS two types of acls */ |
566 | if (S_ISDIR(mode)) | 576 | new_clusters = (S_ISDIR(mode) ? 2 : 1) * |
567 | *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, | 577 | ocfs2_clusters_for_bytes(dir->i_sb, acl_len); |
568 | acl_len); | 578 | *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb, |
579 | new_clusters); | ||
580 | *want_clusters += new_clusters; | ||
569 | } | 581 | } |
570 | 582 | ||
571 | return ret; | 583 | return ret; |