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