Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md: Convert remaining 1k representations in linear.c to sectors.

This patch renames hash_spacing and preshift to spacing and
sector_shift respectively with the following change of semantics:

Case 1: (sizeof(sector_t) <= sizeof(u32)).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In this case, we have sector_shift = preshift = 0 and spacing =
2 * hash_spacing.

Hence, the index for the hash table which is computed by the new code
in which_dev() as sector / spacing equals the old value which was
(sector/2) / hash_spacing.

Note also that the value of nb_zone stays the same because both sz
and base double.

Case 2: (sizeof(sector_t) > sizeof(u32)).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

(aka the shifting dance case). Here we have sector_shift = preshift +
1 and

spacing = 2 * hash_spacing

during the computation of nb_zone and curr_sector, but

spacing = hash_spacing

in which_dev() because in the last hunk of the patch for linear.c we
shift down conf->spacing (= 2 * hash_spacing) by one more bit than
in the old code.

Hence in the computation of nb_zone, sz and base have the same value
as before, so nb_zone is not affected. Also curr_sector in the next
hunk stays the same.

In which_dev() the hash table index is computed as

(sector >> sector_shift) / spacing

In view of sector_shift = preshift + 1 and spacing = hash_spacing,
this equals

((sector/2) >> preshift) / hash_spacing

which is the value computed by the old code.

Signed-off-by: Andre Noll <maan@systemlinux.org>
Signed-off-by: NeilBrown <neilb@suse.de>

authored by

Andre Noll and committed by
NeilBrown
ab5bd5cb 23242fbb

+21 -20
+17 -18
drivers/md/linear.c
··· 33 33 { 34 34 dev_info_t *hash; 35 35 linear_conf_t *conf = mddev_to_conf(mddev); 36 - sector_t block = sector >> 1; 37 36 38 37 /* 39 38 * sector_div(a,b) returns the remainer and sets a to a/b 40 39 */ 41 - block >>= conf->preshift; 42 - (void)sector_div(block, conf->hash_spacing); 43 - hash = conf->hash_table[block]; 40 + sector >>= conf->sector_shift; 41 + (void)sector_div(sector, conf->spacing); 42 + hash = conf->hash_table[sector]; 44 43 45 44 while (sector >= hash->num_sectors + hash->start_sector) 46 45 hash++; ··· 163 164 * that is larger than min_sectors and use the size of that as 164 165 * the actual spacing 165 166 */ 166 - conf->hash_spacing = conf->array_sectors / 2; 167 + conf->spacing = conf->array_sectors; 167 168 for (i=0; i < cnt-1 ; i++) { 168 169 sector_t tmp = 0; 169 170 int j; 170 171 for (j = i; j < cnt - 1 && tmp < min_sectors; j++) 171 172 tmp += conf->disks[j].num_sectors; 172 - if (tmp >= min_sectors && tmp < conf->hash_spacing * 2) 173 - conf->hash_spacing = tmp / 2; 173 + if (tmp >= min_sectors && tmp < conf->spacing) 174 + conf->spacing = tmp; 174 175 } 175 176 176 - /* hash_spacing may be too large for sector_div to work with, 177 + /* spacing may be too large for sector_div to work with, 177 178 * so we might need to pre-shift 178 179 */ 179 - conf->preshift = 0; 180 + conf->sector_shift = 0; 180 181 if (sizeof(sector_t) > sizeof(u32)) { 181 - sector_t space = conf->hash_spacing; 182 + sector_t space = conf->spacing; 182 183 while (space > (sector_t)(~(u32)0)) { 183 184 space >>= 1; 184 - conf->preshift++; 185 + conf->sector_shift++; 185 186 } 186 187 } 187 188 /* ··· 193 194 unsigned round; 194 195 unsigned long base; 195 196 196 - sz = conf->array_sectors >> (conf->preshift + 1); 197 + sz = conf->array_sectors >> conf->sector_shift; 197 198 sz += 1; /* force round-up */ 198 - base = conf->hash_spacing >> conf->preshift; 199 + base = conf->spacing >> conf->sector_shift; 199 200 round = sector_div(sz, base); 200 201 nb_zone = sz + (round ? 1 : 0); 201 202 } ··· 220 221 i = 0; 221 222 for (curr_sector = 0; 222 223 curr_sector < conf->array_sectors; 223 - curr_sector += conf->hash_spacing * 2) { 224 + curr_sector += conf->spacing) { 224 225 225 226 while (i < raid_disks-1 && 226 227 curr_sector >= conf->disks[i+1].start_sector) ··· 229 230 *table ++ = conf->disks + i; 230 231 } 231 232 232 - if (conf->preshift) { 233 - conf->hash_spacing >>= conf->preshift; 234 - /* round hash_spacing up so that when we divide by it, 233 + if (conf->sector_shift) { 234 + conf->spacing >>= conf->sector_shift; 235 + /* round spacing up so that when we divide by it, 235 236 * we err on the side of "too-low", which is safest. 236 237 */ 237 - conf->hash_spacing++; 238 + conf->spacing++; 238 239 } 239 240 240 241 BUG_ON(table - conf->hash_table > nb_zone);
+4 -2
include/linux/raid/linear.h
··· 15 15 { 16 16 struct linear_private_data *prev; /* earlier version */ 17 17 dev_info_t **hash_table; 18 - sector_t hash_spacing; 18 + sector_t spacing; 19 19 sector_t array_sectors; 20 - int preshift; /* shift before dividing by hash_spacing */ 20 + int sector_shift; /* shift before dividing 21 + * by spacing 22 + */ 21 23 dev_info_t disks[0]; 22 24 }; 23 25