Hi, There are two fixes base on tao's patch "remove extend_trans and add its credits at the beginning". They are also base on mark's merge_window branch. The first patch together with tao's patch fix bug http://oss.oracle.com/bugzilla/show_bug.cgi?id=1048 It's a transaction credits issue. The second patch fix a problem when we set security xattr and acl xattr during mknod. When block size is too small, we may need xattr bucket for them. Thanks, tiger
Tiger Yang
2008-Dec-09 08:42 UTC
[Ocfs2-devel] [PATCH 1/2] 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 at oracle.com> --- 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 6860134..510c413 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -456,9 +456,14 @@ int ocfs2_calc_security_init(struct inode *dir, } /* reserve clusters for xattr value which will be set in B tree*/ - if (si->value_len > OCFS2_XATTR_INLINE_SIZE) - *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, - si->value_len); + if (si->value_len > OCFS2_XATTR_INLINE_SIZE) { + int new_clusters = ocfs2_clusters_for_bytes(dir->i_sb, + si->value_len); + + *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb, + new_clusters); + *want_clusters += new_clusters; + } return ret; } @@ -472,9 +477,7 @@ int ocfs2_calc_xattr_init(struct inode *dir, { int ret = 0; struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); - int s_size = 0; - int a_size = 0; - int acl_len = 0; + int s_size = 0, a_size = 0, acl_len = 0, new_clusters; if (si->enable) s_size = ocfs2_xattr_entry_real_size(strlen(si->name), @@ -522,16 +525,25 @@ int ocfs2_calc_xattr_init(struct inode *dir, *xattr_credits += ocfs2_blocks_per_xattr_bucket(dir->i_sb); } - /* reserve clusters for xattr value which will be set in B tree*/ - if (si->enable && si->value_len > OCFS2_XATTR_INLINE_SIZE) - *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, - si->value_len); + /* + * reserve credits and clusters for xattrs which has large value + * and have to be set outside + */ + if (si->enable && si->value_len > OCFS2_XATTR_INLINE_SIZE) { + new_clusters = ocfs2_clusters_for_bytes(dir->i_sb, + si->value_len); + *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb, + new_clusters); + *want_clusters += new_clusters; + } if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL && acl_len > OCFS2_XATTR_INLINE_SIZE) { - *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, acl_len); - if (S_ISDIR(mode)) - *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, - acl_len); + /* for directory, it has DEFAULT and ACCESS two types of acls */ + new_clusters = (S_ISDIR(mode) ? 2 : 1) * + ocfs2_clusters_for_bytes(dir->i_sb, acl_len); + *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb, + new_clusters); + *want_clusters += new_clusters; } return ret; -- 1.5.4.1
Tiger Yang
2008-Dec-09 08:43 UTC
[Ocfs2-devel] [PATCH 2/2] ocfs2: alloc xattr bucket in ocfs2_xattr_set_handle
In extreme situation, may need xattr bucket for setting security entry and acl entries during mknod. This only happens when block size is too small. Signed-off-by: Tiger Yang <tiger.yang at oracle.com> --- fs/ocfs2/xattr.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 510c413..a24cf88 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -2562,9 +2562,7 @@ out: /* * This function only called duing creating inode * for init security/acl xattrs of the new inode. - * The xattrs could be put into ibody or extent block, - * xattr bucket would not be use in this case. - * transanction credits also be reserved in here. + * All transanction credits have been reserved in mknod. */ int ocfs2_xattr_set_handle(handle_t *handle, struct inode *inode, @@ -2604,6 +2602,19 @@ int ocfs2_xattr_set_handle(handle_t *handle, if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb))) return -EOPNOTSUPP; + /* + * In extreme situation, may need xattr bucket when + * block size is too small. And we have already reserved + * the credits for bucket in mknod. + */ + if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE) { + xbs.bucket = ocfs2_xattr_bucket_new(inode); + if (!xbs.bucket) { + mlog_errno(-ENOMEM); + return -ENOMEM; + } + } + xis.inode_bh = xbs.inode_bh = di_bh; di = (struct ocfs2_dinode *)di_bh->b_data; @@ -2623,6 +2634,7 @@ int ocfs2_xattr_set_handle(handle_t *handle, cleanup: up_write(&OCFS2_I(inode)->ip_xattr_sem); brelse(xbs.xattr_bh); + ocfs2_xattr_bucket_free(xbs.bucket); return ret; } -- 1.5.4.1