diff options
author | Mark Fasheh <mfasheh@suse.com> | 2009-02-19 16:17:05 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-04-03 14:39:17 -0400 |
commit | 1d46dc08d33138c29c63d717807c08ab704fc773 (patch) | |
tree | 8e4d2e1b5c49cb379c0f800e00e1cd01d33d4d0c | |
parent | b80b549c3520b31d3bbc4b36e37e0a5102da0b94 (diff) |
ocfs2: fix leaf start calculation in ocfs2_dx_dir_rebalance()
ocfs2_dx_dir_rebalance() is passed the block offset of a dx leaf which needs
rebalancing. Since we rebalance an entire cluster at a time however, this
function needs to calculate the beginning of that cluster, in blocks. The
calculation was wrong, which would result in a read of non-leaf blocks. Fix
the calculation by adding ocfs2_block_to_cluster_start() which is a more
straight-forward way of determining this.
Reported-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r-- | fs/ocfs2/dir.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2.h | 10 |
2 files changed, 11 insertions, 2 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 5e6aeb00cb43..e71160cda110 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -3941,8 +3941,7 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, | |||
3941 | goto out_commit; | 3941 | goto out_commit; |
3942 | } | 3942 | } |
3943 | 3943 | ||
3944 | orig_leaves_start = leaf_blkno & ~(osb->s_clustersize_bits - | 3944 | orig_leaves_start = ocfs2_block_to_cluster_start(dir->i_sb, leaf_blkno); |
3945 | osb->sb->s_blocksize_bits); | ||
3946 | ret = ocfs2_read_dx_leaves(dir, orig_leaves_start, num_dx_leaves, | 3945 | ret = ocfs2_read_dx_leaves(dir, orig_leaves_start, num_dx_leaves, |
3947 | orig_dx_leaves); | 3946 | orig_dx_leaves); |
3948 | if (ret) { | 3947 | if (ret) { |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index fa3c6d3f0bd2..e1844d5736c4 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -582,6 +582,16 @@ static inline u64 ocfs2_clusters_to_bytes(struct super_block *sb, | |||
582 | return (u64)clusters << OCFS2_SB(sb)->s_clustersize_bits; | 582 | return (u64)clusters << OCFS2_SB(sb)->s_clustersize_bits; |
583 | } | 583 | } |
584 | 584 | ||
585 | static inline u64 ocfs2_block_to_cluster_start(struct super_block *sb, | ||
586 | u64 blocks) | ||
587 | { | ||
588 | int bits = OCFS2_SB(sb)->s_clustersize_bits - sb->s_blocksize_bits; | ||
589 | unsigned int clusters; | ||
590 | |||
591 | clusters = ocfs2_blocks_to_clusters(sb, blocks); | ||
592 | return (u64)clusters << bits; | ||
593 | } | ||
594 | |||
585 | static inline u64 ocfs2_align_bytes_to_clusters(struct super_block *sb, | 595 | static inline u64 ocfs2_align_bytes_to_clusters(struct super_block *sb, |
586 | u64 bytes) | 596 | u64 bytes) |
587 | { | 597 | { |