Btrfs: fix off-by-one logic error in btrfs_realloc_node
authorFilipe Manana <fdmanana@suse.com>
Mon, 23 Feb 2015 19:48:52 +0000 (19:48 +0000)
committerChris Mason <clm@fb.com>
Mon, 2 Mar 2015 22:04:45 +0000 (14:04 -0800)
The end_slot variable actually matches the number of pointers in the
node and not the last slot (which is 'nritems - 1'). Therefore in order
to check that the current slot in the for loop doesn't match the last
one, the correct logic is to check if 'i' is less than 'end_slot - 1'
and not 'end_slot - 2'.

Fix this and set end_slot to be 'nritems - 1', as it's less confusing
since the variable name implies it's inclusive rather then exclusive.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/ctree.c

index 9936421..6d67f32 100644 (file)
@@ -1645,14 +1645,14 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
 
        parent_nritems = btrfs_header_nritems(parent);
        blocksize = root->nodesize;
-       end_slot = parent_nritems;
+       end_slot = parent_nritems - 1;
 
-       if (parent_nritems == 1)
+       if (parent_nritems <= 1)
                return 0;
 
        btrfs_set_lock_blocking(parent);
 
-       for (i = start_slot; i < end_slot; i++) {
+       for (i = start_slot; i <= end_slot; i++) {
                int close = 1;
 
                btrfs_node_key(parent, &disk_key, i);
@@ -1669,7 +1669,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
                        other = btrfs_node_blockptr(parent, i - 1);
                        close = close_blocks(blocknr, other, blocksize);
                }
-               if (!close && i < end_slot - 2) {
+               if (!close && i < end_slot) {
                        other = btrfs_node_blockptr(parent, i + 1);
                        close = close_blocks(blocknr, other, blocksize);
                }