Commit a2b12f37 authored by Andrew Morton's avatar Andrew Morton Committed by Patrick Mochel

[PATCH] 64-bit sector_t - remove udivdi3, use sector_div()

From Peter Chubb

Get rid of need for GCC _udivdi3 and _umoddi3 helper functions
 - use sector_div more aggressively.
parent d6b4ef83
...@@ -20,15 +20,3 @@ obj-$(CONFIG_BLK_DEV_LVM) += lvm-mod.o ...@@ -20,15 +20,3 @@ obj-$(CONFIG_BLK_DEV_LVM) += lvm-mod.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
# I can't get around the need for 64-bit division in raid[0-5]
ifdef CONFIG_LBD
LIBGCC:= $(shell ${CC} ${CFLAGS} -print-libgcc-file-name)
md.o: md.c _udivdi3.o _umoddi3.o
$(CC) $(c_flags) -c -o md-tmp.o md.c
$(LD) -r -o md.o md-tmp.o _udivdi3.o _umoddi3.o
_udivdi3.o _umoddi3.o: $(LIBGCC)
$(AR) x $(LIBGCC) $@
endif
...@@ -3479,12 +3479,6 @@ void cleanup_module(void) ...@@ -3479,12 +3479,6 @@ void cleanup_module(void)
} }
#endif #endif
#ifdef CONFIG_LBD
extern u64 __udivdi3(u64, u64);
extern u64 __umoddi3(u64, u64);
EXPORT_SYMBOL(__udivdi3);
EXPORT_SYMBOL(__umoddi3);
#endif
EXPORT_SYMBOL(md_size); EXPORT_SYMBOL(md_size);
EXPORT_SYMBOL(register_md_personality); EXPORT_SYMBOL(register_md_personality);
EXPORT_SYMBOL(unregister_md_personality); EXPORT_SYMBOL(unregister_md_personality);
......
...@@ -144,7 +144,7 @@ static int create_strip_zones (mddev_t *mddev) ...@@ -144,7 +144,7 @@ static int create_strip_zones (mddev_t *mddev)
zone->nb_dev = c; zone->nb_dev = c;
zone->size = (smallest->size - current_offset) * c; zone->size = (smallest->size - current_offset) * c;
printk("raid0: zone->nb_dev: %d, size: %ld\n",zone->nb_dev,zone->size); printk("raid0: zone->nb_dev: %d, size: %llu\n",zone->nb_dev, (unsigned long long)zone->size);
if (!conf->smallest || (zone->size < conf->smallest->size)) if (!conf->smallest || (zone->size < conf->smallest->size))
conf->smallest = zone; conf->smallest = zone;
...@@ -180,9 +180,15 @@ static int raid0_run (mddev_t *mddev) ...@@ -180,9 +180,15 @@ static int raid0_run (mddev_t *mddev)
goto out_free_conf; goto out_free_conf;
printk("raid0 : md_size is %llu blocks.\n", (unsigned long long)md_size[mdidx(mddev)]); printk("raid0 : md_size is %llu blocks.\n", (unsigned long long)md_size[mdidx(mddev)]);
printk("raid0 : conf->smallest->size is %ld blocks.\n", conf->smallest->size); printk("raid0 : conf->smallest->size is %llu blocks.\n", (unsigned long long)conf->smallest->size);
nb_zone = md_size[mdidx(mddev)]/conf->smallest->size + {
(md_size[mdidx(mddev)] % conf->smallest->size ? 1 : 0); #if __GNUC__ < 3
volatile
#endif
sector_t s = md_size[mdidx(mddev)];
int round = sector_div(s, (unsigned long)conf->smallest->size) ? 1 : 0;
nb_zone = s + round;
}
printk("raid0 : nb_zone is %d.\n", nb_zone); printk("raid0 : nb_zone is %d.\n", nb_zone);
conf->nr_zones = nb_zone; conf->nr_zones = nb_zone;
...@@ -277,10 +283,16 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio) ...@@ -277,10 +283,16 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
chunk_size = mddev->chunk_size >> 10; chunk_size = mddev->chunk_size >> 10;
chunksize_bits = ffz(~chunk_size); chunksize_bits = ffz(~chunk_size);
block = bio->bi_sector >> 1; block = bio->bi_sector >> 1;
hash = conf->hash_table + block / conf->smallest->size;
{
sector_t x = block;
sector_div(x, (unsigned long)conf->smallest->size);
hash = conf->hash_table + x;
}
/* Sanity check */ /* Sanity check */
if (chunk_size < (block % chunk_size) + (bio->bi_size >> 10)) if (chunk_size < (block & (chunk_size - 1)) + (bio->bi_size >> 10))
goto bad_map; goto bad_map;
if (!hash) if (!hash)
...@@ -297,8 +309,18 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio) ...@@ -297,8 +309,18 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
zone = hash->zone0; zone = hash->zone0;
sect_in_chunk = bio->bi_sector & ((chunk_size<<1) -1); sect_in_chunk = bio->bi_sector & ((chunk_size<<1) -1);
chunk = (block - zone->zone_offset) / (zone->nb_dev << chunksize_bits);
tmp_dev = zone->dev[(block >> chunksize_bits) % zone->nb_dev];
{
sector_t x = block - zone->zone_offset;
sector_div(x, (zone->nb_dev << chunksize_bits));
chunk = x;
BUG_ON(x != (sector_t)chunk);
x = block >> chunksize_bits;
tmp_dev = zone->dev[sector_div(x, zone->nb_dev)];
}
rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1) rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1)
+ sect_in_chunk; + sect_in_chunk;
......
...@@ -30,13 +30,15 @@ ...@@ -30,13 +30,15 @@
#define NR_STRIPES 256 #define NR_STRIPES 256
#define STRIPE_SIZE PAGE_SIZE #define STRIPE_SIZE PAGE_SIZE
#define STRIPE_SHIFT (PAGE_SHIFT - 9)
#define STRIPE_SECTORS (STRIPE_SIZE>>9) #define STRIPE_SECTORS (STRIPE_SIZE>>9)
#define IO_THRESHOLD 1 #define IO_THRESHOLD 1
#define HASH_PAGES 1 #define HASH_PAGES 1
#define HASH_PAGES_ORDER 0 #define HASH_PAGES_ORDER 0
#define NR_HASH (HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *)) #define NR_HASH (HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
#define HASH_MASK (NR_HASH - 1) #define HASH_MASK (NR_HASH - 1)
#define stripe_hash(conf, sect) ((conf)->stripe_hashtbl[((sect) / STRIPE_SECTORS) & HASH_MASK])
#define stripe_hash(conf, sect) ((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK])
/* /*
* The following can be used to debug the driver * The following can be used to debug the driver
...@@ -482,7 +484,7 @@ static unsigned long raid5_compute_sector(sector_t r_sector, unsigned int raid_d ...@@ -482,7 +484,7 @@ static unsigned long raid5_compute_sector(sector_t r_sector, unsigned int raid_d
unsigned int data_disks, unsigned int * dd_idx, unsigned int data_disks, unsigned int * dd_idx,
unsigned int * pd_idx, raid5_conf_t *conf) unsigned int * pd_idx, raid5_conf_t *conf)
{ {
sector_t stripe; long stripe;
unsigned long chunk_number; unsigned long chunk_number;
unsigned int chunk_offset; unsigned int chunk_offset;
sector_t new_sector; sector_t new_sector;
...@@ -493,8 +495,9 @@ static unsigned long raid5_compute_sector(sector_t r_sector, unsigned int raid_d ...@@ -493,8 +495,9 @@ static unsigned long raid5_compute_sector(sector_t r_sector, unsigned int raid_d
/* /*
* Compute the chunk number and the sector offset inside the chunk * Compute the chunk number and the sector offset inside the chunk
*/ */
chunk_number = r_sector / sectors_per_chunk; chunk_offset = sector_div(r_sector, sectors_per_chunk);
chunk_offset = r_sector % sectors_per_chunk; chunk_number = r_sector;
BUG_ON(r_sector != chunk_number);
/* /*
* Compute the stripe number * Compute the stripe number
...@@ -548,11 +551,16 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) ...@@ -548,11 +551,16 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
int raid_disks = conf->raid_disks, data_disks = raid_disks - 1; int raid_disks = conf->raid_disks, data_disks = raid_disks - 1;
sector_t new_sector = sh->sector, check; sector_t new_sector = sh->sector, check;
int sectors_per_chunk = conf->chunk_size >> 9; int sectors_per_chunk = conf->chunk_size >> 9;
sector_t stripe = new_sector / sectors_per_chunk; long stripe;
int chunk_offset = new_sector % sectors_per_chunk; int chunk_offset;
int chunk_number, dummy1, dummy2, dd_idx = i; int chunk_number, dummy1, dummy2, dd_idx = i;
sector_t r_sector; sector_t r_sector;
chunk_offset = sector_div(new_sector, sectors_per_chunk);
stripe = new_sector;
BUG_ON(new_sector != stripe);
switch (conf->algorithm) { switch (conf->algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC: case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC: case ALGORITHM_RIGHT_ASYMMETRIC:
...@@ -570,7 +578,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) ...@@ -570,7 +578,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
} }
chunk_number = stripe * data_disks + i; chunk_number = stripe * data_disks + i;
r_sector = chunk_number * sectors_per_chunk + chunk_offset; r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
...@@ -1285,8 +1293,9 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -1285,8 +1293,9 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
raid5_conf_t *conf = (raid5_conf_t *) mddev->private; raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh; struct stripe_head *sh;
int sectors_per_chunk = conf->chunk_size >> 9; int sectors_per_chunk = conf->chunk_size >> 9;
unsigned long stripe = sector_nr/sectors_per_chunk; sector_t x;
int chunk_offset = sector_nr % sectors_per_chunk; unsigned long stripe;
int chunk_offset;
int dd_idx, pd_idx; int dd_idx, pd_idx;
unsigned long first_sector; unsigned long first_sector;
int raid_disks = conf->raid_disks; int raid_disks = conf->raid_disks;
...@@ -1296,6 +1305,11 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -1296,6 +1305,11 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
/* just being told to finish up .. nothing to do */ /* just being told to finish up .. nothing to do */
return 0; return 0;
x = sector_nr;
chunk_offset = sector_div(x, sectors_per_chunk);
stripe = x;
BUG_ON(x != stripe);
first_sector = raid5_compute_sector(stripe*data_disks*sectors_per_chunk first_sector = raid5_compute_sector(stripe*data_disks*sectors_per_chunk
+ chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf); + chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf);
sh = get_active_stripe(conf, sector_nr, pd_idx, 0); sh = get_active_stripe(conf, sector_nr, pd_idx, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment