Skip to content

Commit

Permalink
md: Fix a bug in linear.c causing which_dev() to return the wrong dev…
Browse files Browse the repository at this point in the history
…ice.

ab5bd5c introduced the following
bug in linear software raid for large arrays on 32 bit machines:

which_dev() computes the device holding a given sector by shifting
down the sector number to a 32 bit range, dividing by the array
spacing and looking up the resulting index in the hash table of
the array.

Because the computed index might be slightly too small, a loop at
the end of which_dev() increases the index until the given sector
actually falls into the range of the device associated with that index.

The changes of the above mentioned commit caused this loop to check
whether the _index_ rather than the sector number is small enough,
effectively bypassing the loop and thus possibly returning the wrong
device.

As reported by Simon Kirby, this leads to errors such as

	linear_make_request: Sector 2340486136 out of bounds on dev sdi: 156301312 sectors, offset 2109870464

Fix this bug by introducing a local variable for the index so that
the variable containing the passed sector is left unchanged.

Cc: stable@kernel.org
Signed-off-by: Andre Noll <maan@systemlinux.org>
Signed-off-by: NeilBrown <neilb@suse.de>
  • Loading branch information
Andre Noll authored and NeilBrown committed Feb 6, 2009
1 parent 4706b34 commit 852c8bf
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions drivers/md/linear.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
{
dev_info_t *hash;
linear_conf_t *conf = mddev_to_conf(mddev);
sector_t idx = sector >> conf->sector_shift;

/*
* sector_div(a,b) returns the remainer and sets a to a/b
*/
sector >>= conf->sector_shift;
(void)sector_div(sector, conf->spacing);
hash = conf->hash_table[sector];
(void)sector_div(idx, conf->spacing);
hash = conf->hash_table[idx];

while (sector >= hash->num_sectors + hash->start_sector)
hash++;
Expand Down

0 comments on commit 852c8bf

Please sign in to comment.