diff options
| -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 73fb9f76251..e5be470e750 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; |
