aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorTiger Yang <tiger.yang@oracle.com>2008-12-09 03:42:51 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:36 -0500
commit0e445b6fe93c723fe8093fd04ddfeb11ae2de082 (patch)
treea7c2d8ccab64ef70477992b0121dd52966c66154 /fs/ocfs2/xattr.c
parent90cb546cada68bb8c2278afdb4b65c2ac11f2877 (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/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c40
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;