aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-09-08 05:21:13 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-10-21 07:39:46 -0400
commitf75bbfb4dda68c86eb33cde7e2b5c1343c6d5812 (patch)
tree42d5f7a3637061cddc3170aac8e57c4933007898 /fs/gfs2/rgrp.c
parent13d921e37174e3d1042deeb303537c1d935da553 (diff)
GFS2: Fix off-by-one in gfs2_blk2rgrpd
Bob reported: I found an off-by-one problem with how I coded this section: It should be: + else if (blk >= cur->rd_data0 + cur->rd_data) In fact, cur->rd_data0 + cur->rd_data is the start of the next rgrp (the next ri_addr), so without the "=" check it can land on the wrong rgrp. In all normal cases, this won't be a problem: you're searching for a block _within_ the rgrp, which will pass the test properly. Where it gets into trouble is if you search the rgrps for the block exactly equal to ri_addr. I don't think anything in the kernel does this, but I found a place in gfs2-utils gfs2_edit where it does. So I definitely need to fix it in libgfs2. I'd like to suggest we fix it in the kernel as well for the sake of keeping the functions similar. So this patch fixes the above mentioned off by one error as well as removing the unused parent pointer. Reported-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 8ec41744594..1daf8a78c73 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -329,17 +329,16 @@ static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block)
329 329
330struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) 330struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk)
331{ 331{
332 struct rb_node **newn, *parent = NULL; 332 struct rb_node **newn;
333 struct gfs2_rgrpd *cur;
333 334
334 spin_lock(&sdp->sd_rindex_spin); 335 spin_lock(&sdp->sd_rindex_spin);
335 newn = &sdp->sd_rindex_tree.rb_node; 336 newn = &sdp->sd_rindex_tree.rb_node;
336 while (*newn) { 337 while (*newn) {
337 struct gfs2_rgrpd *cur = rb_entry(*newn, struct gfs2_rgrpd, 338 cur = rb_entry(*newn, struct gfs2_rgrpd, rd_node);
338 rd_node);
339 parent = *newn;
340 if (blk < cur->rd_addr) 339 if (blk < cur->rd_addr)
341 newn = &((*newn)->rb_left); 340 newn = &((*newn)->rb_left);
342 else if (blk > cur->rd_data0 + cur->rd_data) 341 else if (blk >= cur->rd_data0 + cur->rd_data)
343 newn = &((*newn)->rb_right); 342 newn = &((*newn)->rb_right);
344 else { 343 else {
345 spin_unlock(&sdp->sd_rindex_spin); 344 spin_unlock(&sdp->sd_rindex_spin);