* [Ocfs2-devel] [PATCH 0/2] Two b-tree bug fixes.
@ 2009-07-21 7:35 Tao Ma
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 1/2] ocfs2: Add extra credits and access the modified bh in update_edge_lengths Tao Ma
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records Tao Ma
0 siblings, 2 replies; 9+ messages in thread
From: Tao Ma @ 2009-07-21 7:35 UTC (permalink / raw)
To: ocfs2-devel
Hi Mark/Joel,
These are 2 bug fix for b-tree. Please review.
I have sent out the first one last week, but it was based on cacheme.
So resend it. Now it bases on joel's fixes branch.
The second one is another b-tree rotation bug. I guess the reason why
we never meet with it is that no one has ever used b-tree like reflink
before. ;)
Regards,
Tao
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 1/2] ocfs2: Add extra credits and access the modified bh in update_edge_lengths.
2009-07-21 7:35 [Ocfs2-devel] [PATCH 0/2] Two b-tree bug fixes Tao Ma
@ 2009-07-21 7:42 ` Tao Ma
2009-07-21 21:47 ` Joel Becker
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records Tao Ma
1 sibling, 1 reply; 9+ messages in thread
From: Tao Ma @ 2009-07-21 7:42 UTC (permalink / raw)
To: ocfs2-devel
In normal tree rotation left process, we will never touch the tree
branch above subtree_index and ocfs2_extend_rotate_transaction doesn't
reserve the credits for them either.
But when we want to delete the rightmost extent block, we have to update
the rightmost records for all the rightmost branch(See
ocfs2_update_edge_lengths), so we have to allocate extra credits for them.
What's more, we have to access them also.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
---
fs/ocfs2/alloc.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 9edcde4..11085af 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -2476,15 +2476,37 @@ out_ret_path:
return ret;
}
-static void ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle,
- struct ocfs2_path *path)
+static int ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle,
+ int subtree_index, struct ocfs2_path *path)
{
- int i, idx;
+ int i, idx, ret;
struct ocfs2_extent_rec *rec;
struct ocfs2_extent_list *el;
struct ocfs2_extent_block *eb;
u32 range;
+ /*
+ * In normal tree rotation process, we will never touch the
+ * tree branch above subtree_index and ocfs2_extend_rotate_transaction
+ * doesn't reserve the credits for them either.
+ *
+ * But we do have a special case here which will update the rightmost
+ * records for all the bh in the path.
+ * So we have to allocate extra credits and access them.
+ */
+ ret = ocfs2_extend_trans(handle,
+ handle->h_buffer_credits + subtree_index);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ret = ocfs2_journal_access_path(inode, handle, path);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
/* Path should always be rightmost. */
eb = (struct ocfs2_extent_block *)path_leaf_bh(path)->b_data;
BUG_ON(eb->h_next_leaf_blk != 0ULL);
@@ -2505,6 +2527,8 @@ static void ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle,
ocfs2_journal_dirty(handle, path->p_node[i].bh);
}
+out:
+ return ret;
}
static void ocfs2_unlink_path(struct inode *inode, handle_t *handle,
@@ -2717,7 +2741,12 @@ static int ocfs2_rotate_subtree_left(struct inode *inode, handle_t *handle,
if (del_right_subtree) {
ocfs2_unlink_subtree(inode, handle, left_path, right_path,
subtree_index, dealloc);
- ocfs2_update_edge_lengths(inode, handle, left_path);
+ ret = ocfs2_update_edge_lengths(inode, handle, subtree_index,
+ left_path);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data;
ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno));
@@ -3034,7 +3063,12 @@ static int ocfs2_remove_rightmost_path(struct inode *inode, handle_t *handle,
ocfs2_unlink_subtree(inode, handle, left_path, path,
subtree_index, dealloc);
- ocfs2_update_edge_lengths(inode, handle, left_path);
+ ret = ocfs2_update_edge_lengths(inode, handle, subtree_index,
+ left_path);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data;
ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno));
--
1.6.2.rc2.16.gf474c
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records.
2009-07-21 7:35 [Ocfs2-devel] [PATCH 0/2] Two b-tree bug fixes Tao Ma
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 1/2] ocfs2: Add extra credits and access the modified bh in update_edge_lengths Tao Ma
@ 2009-07-21 7:42 ` Tao Ma
2009-07-21 21:40 ` Joel Becker
1 sibling, 1 reply; 9+ messages in thread
From: Tao Ma @ 2009-07-21 7:42 UTC (permalink / raw)
To: ocfs2-devel
In ocfs2_adjust_adjacent_records, we will adjust adjacent records
according to the extent_list in the lower level. But actually
the lower level tree will either be a leaf or a branch. So we
shouldn't use ocfs2_is_empty_extent which is only valid for a
tree leaf. Use ocfs2_rec_clusters instead. We will meet with some
problem when the tree depth > 2.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
---
fs/ocfs2/alloc.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 11085af..1957645 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1914,7 +1914,7 @@ static void ocfs2_adjust_adjacent_records(struct ocfs2_extent_rec *left_rec,
* immediately to their right.
*/
left_clusters = le32_to_cpu(right_child_el->l_recs[0].e_cpos);
- if (ocfs2_is_empty_extent(&right_child_el->l_recs[0])) {
+ if (!ocfs2_rec_clusters(right_child_el, &right_child_el->l_recs[0])) {
BUG_ON(le16_to_cpu(right_child_el->l_next_free_rec) <= 1);
left_clusters = le32_to_cpu(right_child_el->l_recs[1].e_cpos);
}
--
1.6.2.rc2.16.gf474c
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records.
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records Tao Ma
@ 2009-07-21 21:40 ` Joel Becker
2009-07-22 0:32 ` Tao Ma
0 siblings, 1 reply; 9+ messages in thread
From: Joel Becker @ 2009-07-21 21:40 UTC (permalink / raw)
To: ocfs2-devel
On Tue, Jul 21, 2009 at 03:42:06PM +0800, Tao Ma wrote:
> In ocfs2_adjust_adjacent_records, we will adjust adjacent records
> according to the extent_list in the lower level. But actually
> the lower level tree will either be a leaf or a branch. So we
> shouldn't use ocfs2_is_empty_extent which is only valid for a
> tree leaf. Use ocfs2_rec_clusters instead. We will meet with some
> problem when the tree depth > 2.
I think you mean "if we leave it as checking e_leaf_clusters,
we'll have a problem rotating trees with depth > 2". Is that right?
Can interior nodes have these empty l_rec[0]s? If they can't, perhaps
we should be bugging?
Joel
--
Life's Little Instruction Book #24
"Drink champagne for no reason at all."
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 1/2] ocfs2: Add extra credits and access the modified bh in update_edge_lengths.
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 1/2] ocfs2: Add extra credits and access the modified bh in update_edge_lengths Tao Ma
@ 2009-07-21 21:47 ` Joel Becker
0 siblings, 0 replies; 9+ messages in thread
From: Joel Becker @ 2009-07-21 21:47 UTC (permalink / raw)
To: ocfs2-devel
On Tue, Jul 21, 2009 at 03:42:05PM +0800, Tao Ma wrote:
> In normal tree rotation left process, we will never touch the tree
> branch above subtree_index and ocfs2_extend_rotate_transaction doesn't
> reserve the credits for them either.
>
> But when we want to delete the rightmost extent block, we have to update
> the rightmost records for all the rightmost branch(See
> ocfs2_update_edge_lengths), so we have to allocate extra credits for them.
> What's more, we have to access them also.
>
> Signed-off-by: Tao Ma <tao.ma@oracle.com>
This patch is now in the fixes branch of ocfs2.git.
Joel
--
"Hey mister if you're gonna walk on water,
Could you drop a line my way?"
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records.
2009-07-21 21:40 ` Joel Becker
@ 2009-07-22 0:32 ` Tao Ma
2009-07-22 1:13 ` Joel Becker
0 siblings, 1 reply; 9+ messages in thread
From: Tao Ma @ 2009-07-22 0:32 UTC (permalink / raw)
To: ocfs2-devel
Joel Becker wrote:
> On Tue, Jul 21, 2009 at 03:42:06PM +0800, Tao Ma wrote:
>
>> In ocfs2_adjust_adjacent_records, we will adjust adjacent records
>> according to the extent_list in the lower level. But actually
>> the lower level tree will either be a leaf or a branch. So we
>> shouldn't use ocfs2_is_empty_extent which is only valid for a
>> tree leaf. Use ocfs2_rec_clusters instead. We will meet with some
>> problem when the tree depth > 2.
>>
>
> I think you mean "if we leave it as checking e_leaf_clusters,
> we'll have a problem rotating trees with depth > 2". Is that right?
> Can interior nodes have these empty l_rec[0]s? If they can't, perhaps
> we should be bugging?
>
sorry, It should be tree_depth >=2.
ocfs2_adjust_adjacent_records is used to for rotation. And it only use
e_cpos in most cases.
So we don't have a problem if the lower 16 bits of e_int_clusters isn't
equal to 0 for a branch.
But if the low 16 bits are 0, this ocfs2_is_empty_extent will treat it
as an empty record and use the l_recs[1] which will corrupt
the tree. So let me give you a test case I meet.
Tree Depth: 2 Count: 23 Next Free Rec: 2
## Offset Clusters Block#
0 0 9107457 28721
1 9107457 1922049 28728
Tree Depth: 1 Count: 28 Next Free Rec: 28
## Offset Clusters Block#
0 0 227105 28698
1 227105 197405 28699
...
26 8372225 542208 28725
27 8914433 193024 28726
Tree Depth: 1 Count: 28 Next Free Rec: 10
## Offset Clusters Block#
0 9107457 196608 28727
1 9304065 204544 28729
In this case: 196608=0x30000, so if we use ocfs2_is_empty_extent will
treat it as 0, and use 9394065.
Regards,
Tao
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records.
2009-07-22 0:32 ` Tao Ma
@ 2009-07-22 1:13 ` Joel Becker
2009-07-23 0:12 ` [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records. v2 Tao Ma
0 siblings, 1 reply; 9+ messages in thread
From: Joel Becker @ 2009-07-22 1:13 UTC (permalink / raw)
To: ocfs2-devel
On Wed, Jul 22, 2009 at 08:32:32AM +0800, Tao Ma wrote:
> Joel Becker wrote:
> >On Tue, Jul 21, 2009 at 03:42:06PM +0800, Tao Ma wrote:
> >>In ocfs2_adjust_adjacent_records, we will adjust adjacent records
> >>according to the extent_list in the lower level. But actually
> >>the lower level tree will either be a leaf or a branch. So we
> >>shouldn't use ocfs2_is_empty_extent which is only valid for a
> >>tree leaf. Use ocfs2_rec_clusters instead. We will meet with some
> >>problem when the tree depth > 2.
> >
> > I think you mean "if we leave it as checking e_leaf_clusters,
> >we'll have a problem rotating trees with depth > 2". Is that right?
> >Can interior nodes have these empty l_rec[0]s? If they can't, perhaps
> >we should be bugging?
> sorry, It should be tree_depth >=2.
>
> ocfs2_adjust_adjacent_records is used to for rotation. And it only
> use e_cpos in most cases.
> So we don't have a problem if the lower 16 bits of e_int_clusters
> isn't equal to 0 for a branch.
> But if the low 16 bits are 0, this ocfs2_is_empty_extent will treat
> it as an empty record and use the l_recs[1] which will corrupt
> the tree. So let me give you a test case I meet.
Oh, I understand the problem. My comment above was that it
sounds like you said "Here's a fix, but the fix will still have problems
if tree depth is greater than two". I think you mean "without this fix
we have problems when tree depth is greater than (or equal to) two".
We need the fix. Now let's figure out if we should bug on
interior children.
Joel
--
"Three o'clock is always too late or too early for anything you
want to do."
- Jean-Paul Sartre
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records. v2
2009-07-22 1:13 ` Joel Becker
@ 2009-07-23 0:12 ` Tao Ma
2009-07-23 18:10 ` Joel Becker
0 siblings, 1 reply; 9+ messages in thread
From: Tao Ma @ 2009-07-23 0:12 UTC (permalink / raw)
To: ocfs2-devel
Hi Joel,
how about this? I add a bug_on and change the commit log some how.
Regards,
Tao
In ocfs2_adjust_adjacent_records, we will adjust adjacent records
according to the extent_list in the lower level. But actually
the lower level tree will either be a leaf or a branch. If we only
use ocfs2_is_empty_extent we will meet with some problem if the lower
tree is a branch(tree_depth > 1). So use !ocfs2_rec_clusters instead.
And actually only the leaf record can have holes. So add a BUG_ON
for non-leaf branch.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
---
fs/ocfs2/alloc.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 11085af..f9a3e89 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1914,7 +1914,8 @@ static void ocfs2_adjust_adjacent_records(struct ocfs2_extent_rec *left_rec,
* immediately to their right.
*/
left_clusters = le32_to_cpu(right_child_el->l_recs[0].e_cpos);
- if (ocfs2_is_empty_extent(&right_child_el->l_recs[0])) {
+ if (!ocfs2_rec_clusters(right_child_el, &right_child_el->l_recs[0])) {
+ BUG_ON(right_child_el->l_tree_depth);
BUG_ON(le16_to_cpu(right_child_el->l_next_free_rec) <= 1);
left_clusters = le32_to_cpu(right_child_el->l_recs[1].e_cpos);
}
--
1.6.2.rc2.16.gf474c
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records. v2
2009-07-23 0:12 ` [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records. v2 Tao Ma
@ 2009-07-23 18:10 ` Joel Becker
0 siblings, 0 replies; 9+ messages in thread
From: Joel Becker @ 2009-07-23 18:10 UTC (permalink / raw)
To: ocfs2-devel
On Thu, Jul 23, 2009 at 08:12:58AM +0800, Tao Ma wrote:
> Hi Joel,
> how about this? I add a bug_on and change the commit log some how.
>
> Regards,
> Tao
>
> In ocfs2_adjust_adjacent_records, we will adjust adjacent records
> according to the extent_list in the lower level. But actually
> the lower level tree will either be a leaf or a branch. If we only
> use ocfs2_is_empty_extent we will meet with some problem if the lower
> tree is a branch(tree_depth > 1). So use !ocfs2_rec_clusters instead.
> And actually only the leaf record can have holes. So add a BUG_ON
> for non-leaf branch.
>
> Signed-off-by: Tao Ma <tao.ma@oracle.com>
This is now in the fixes branch of ocfs2.git.
Joel
--
"The cynics are right nine times out of ten."
- H. L. Mencken
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-07-23 18:10 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-21 7:35 [Ocfs2-devel] [PATCH 0/2] Two b-tree bug fixes Tao Ma
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 1/2] ocfs2: Add extra credits and access the modified bh in update_edge_lengths Tao Ma
2009-07-21 21:47 ` Joel Becker
2009-07-21 7:42 ` [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records Tao Ma
2009-07-21 21:40 ` Joel Becker
2009-07-22 0:32 ` Tao Ma
2009-07-22 1:13 ` Joel Becker
2009-07-23 0:12 ` [Ocfs2-devel] [PATCH 2/2] ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records. v2 Tao Ma
2009-07-23 18:10 ` Joel Becker
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.