]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] 64-bit sector_t - various driver changes
authorAndrew Morton <akpm@digeo.com>
Wed, 9 Oct 2002 01:37:17 +0000 (18:37 -0700)
committerPatrick Mochel <mochel@osdl.org>
Wed, 9 Oct 2002 01:37:17 +0000 (18:37 -0700)
peter's code works for me, and the 40-odd people who download
the -mm patches.  Anton has tested it on ppc64 and I presume that
Peter has tested it on ia64.  I use gcc-2.91.66 and others use
later compilers.  I expect that any remaining problems will
mainly be caught by the compiler.  And compiler bugs can be
detected by turning off the option in config and seeing if things
get better.

From Peter Chubb

 - do_request() function takes sector_t not unsigned long as the
   block number to operate on.
 - Various casts to long where the underlying device can never get
   big enough to warrant a 64-bit sector offset.
 - Cast sector_t to unsigned long long when printing.

13 files changed:
drivers/block/blkpg.c
drivers/block/floppy.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-floppy.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/scsi/ide-scsi.c
fs/partitions/check.c
fs/partitions/check.h
include/linux/blkdev.h
include/linux/genhd.h
include/linux/ide.h

index 157b353f7a3302e2139354ccfde786016b5107c9..d5ba72a8ac86b246b9490c00d9ced6a20b9d298b 100644 (file)
@@ -68,17 +68,22 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
 {
        struct gendisk *g;
        long long ppstart, pplength;
-       long pstart, plength;
        int part, i;
 
-       /* convert bytes to sectors, check for fit in a hd_struct */
+       /* convert bytes to sectors */
        ppstart = (p->start >> 9);
        pplength = (p->length >> 9);
-       pstart = ppstart;
-       plength = pplength;
-       if (pstart != ppstart || plength != pplength
-           || pstart < 0 || plength < 0)
-               return -EINVAL;
+
+       /* check for fit in a hd_struct */ 
+       if (sizeof(sector_t) == sizeof(long) && 
+           sizeof(long long) > sizeof(long)) {
+               long pstart, plength;
+               pstart = ppstart;
+               plength = pplength;
+               if (pstart != ppstart || plength != pplength
+                   || pstart < 0 || plength < 0)
+                       return -EINVAL;
+       }
 
        /* find the drive major */
        g = get_gendisk(bdev->bd_dev, &part);
@@ -101,13 +106,13 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
 
        /* overlap? */
        for (i = 0; i < (1<<g->minor_shift) - 1; i++)
-               if (!(pstart+plength <= g->part[i].start_sect ||
-                     pstart >= g->part[i].start_sect + g->part[i].nr_sects))
+               if (!(ppstart+pplength <= g->part[i].start_sect ||
+                     ppstart >= g->part[i].start_sect + g->part[i].nr_sects))
                        return -EBUSY;
 
        /* all seems OK */
-       g->part[p->pno - 1].start_sect = pstart;
-       g->part[p->pno - 1].nr_sects = plength;
+       g->part[p->pno - 1].start_sect = ppstart;
+       g->part[p->pno - 1].nr_sects = pplength;
        update_partition(g, p->pno);
        return 0;
 }
@@ -259,10 +264,17 @@ int blk_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long arg)
                        intval = bdev_hardsect_size(bdev);
                        return put_user(intval, (int *) arg);
 
-               case BLKGETSIZE:
+               case BLKGETSIZE: 
+               {
+                       unsigned long ret;
                        /* size in sectors, works up to 2 TB */
                        ullval = bdev->bd_inode->i_size;
-                       return put_user((unsigned long)(ullval >> 9), (unsigned long *) arg);
+                       ret = ullval >> 9;
+                       if ((u64)ret != (ullval >> 9))
+                               return -EFBIG;
+                       return put_user(ret, (unsigned long *) arg);
+               }
+               
                case BLKGETSIZE64:
                        /* size in bytes */
                        ullval = bdev->bd_inode->i_size;
index 943b0c672646934ec63599f3d4d10af4dfaccf1f..924e1e011f76364784f1bb69835ab00698126f2d 100644 (file)
@@ -492,7 +492,7 @@ static struct floppy_struct *current_type[N_DRIVE];
  */
 static struct floppy_struct user_params[N_DRIVE];
 
-static int floppy_sizes[256];
+static sector_t floppy_sizes[256];
 
 /*
  * The driver is trying to determine the correct media format
@@ -2652,8 +2652,8 @@ static int make_raw_rw_request(void)
 
        max_sector = _floppy->sect * _floppy->head;
 
-       TRACK = current_req->sector / max_sector;
-       fsector_t = current_req->sector % max_sector;
+       TRACK = (int)current_req->sector / max_sector;
+       fsector_t = (int)current_req->sector % max_sector;
        if (_floppy->track && TRACK >= _floppy->track) {
                if (current_req->current_nr_sectors & 1) {
                        current_count_sectors = 1;
@@ -2990,7 +2990,7 @@ static void do_fd_request(request_queue_t * q)
 
        if (usage_count == 0) {
                printk("warning: usage count=0, current_req=%p exiting\n", current_req);
-               printk("sect=%ld flags=%lx\n", current_req->sector, current_req->flags);
+               printk("sect=%ld flags=%lx\n", (long)current_req->sector, current_req->flags);
                return;
        }
        if (fdc_busy){
index d86ecca4b05ab34e8607fad9de84c5d8c5581575..fd3d89421421acbfcf2cd4431c3bb02c6d51281d 100644 (file)
@@ -1163,7 +1163,7 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
        if (rq->current_nr_sectors < bio_sectors(rq->bio) &&
            (rq->sector % SECTORS_PER_FRAME) != 0) {
                printk("%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
-                       drive->name, rq->sector);
+                       drive->name, (long)rq->sector);
                cdrom_end_request(drive, 0);
                return -1;
        }
@@ -1750,7 +1750,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
  * cdrom driver request routine.
  */
 static ide_startstop_t
-ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long block)
+ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
 {
        ide_startstop_t action;
        struct cdrom_info *info = drive->driver_data;
@@ -2775,12 +2775,14 @@ static void ide_cdrom_add_settings(ide_drive_t *drive)
 static int ll_10byte_cmd_build(request_queue_t *q, struct request *rq)
 {
        int hard_sect = queue_hardsect_size(q);
-       sector_t block = rq->hard_sector / (hard_sect >> 9);
+       long block = (long)rq->hard_sector / (hard_sect >> 9);
        unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
 
        if (!(rq->flags & REQ_CMD))
                return 0;
 
+       BUG_ON(sizeof(rq->hard_sector) > 4 && (rq->hard_sector >> 32));
+
        if (rq->hard_nr_sectors != rq->nr_sectors) {
                printk(KERN_ERR "ide-cd: hard_nr_sectors differs from nr_sectors! %lu %lu\n",
                                rq->nr_sectors, rq->hard_nr_sectors);
index 19e0e9f1d8639e857cabe63b863ef0c6a8da955c..419ef498c15154f49a4d19bacb5ade48be4b9fd7 100644 (file)
@@ -371,7 +371,7 @@ static int idedisk_start_tag(ide_drive_t *drive, struct request *rq)
  * using LBA if supported, or CHS otherwise, to address sectors.
  * It also takes care of issuing special DRIVE_CMDs.
  */
-static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        u8 lba48                = (drive->addressing == 1) ? 1 : 0;
@@ -418,10 +418,13 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
                        tasklets[5] = (task_ioreg_t) (block>>8);
                        tasklets[6] = (task_ioreg_t) (block>>16);
                        tasklets[7] = (task_ioreg_t) (block>>24);
-                       tasklets[8] = (task_ioreg_t) 0;
-                       tasklets[9] = (task_ioreg_t) 0;
-//                     tasklets[8] = (task_ioreg_t) (block>>32);
-//                     tasklets[9] = (task_ioreg_t) (block>>40);
+                       if (sizeof(block) == 4) {
+                               tasklets[8] = (task_ioreg_t) 0;
+                               tasklets[9] = (task_ioreg_t) 0;
+                       } else {
+                               tasklets[8] = (task_ioreg_t)((u64)block >> 32);
+                               tasklets[9] = (task_ioreg_t)((u64)block >> 40);
+                       }
 #ifdef DEBUG
                        printk("%s: %sing: LBAsect=%lu, sectors=%ld, "
                                "buffer=0x%08lx, LBAsect=0x%012lx\n",
@@ -450,10 +453,11 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
                        hwif->OUTB(0x00|drive->select.all,IDE_SELECT_REG);
                } else {
 #ifdef DEBUG
-                       printk("%s: %sing: LBAsect=%ld, sectors=%d, "
+                       printk("%s: %sing: LBAsect=%llu, sectors=%ld, "
                                "buffer=0x%08lx\n",
-                               drive->name,rq_data_dir(rq)==READ?"read":"writ",
-                               block, nsectors.b.low,
+                               drive->name,
+                               rq_data_dir(rq)==READ?"read":"writ",
+                               (unsigned long long)block, rq->nr_sectors,
                                (unsigned long) rq->buffer);
 #endif
                        if (blk_rq_tagged(rq)) {
@@ -471,8 +475,8 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
                }
        } else {
                unsigned int sect,head,cyl,track;
-               track = block / drive->sect;
-               sect  = block % drive->sect + 1;
+               track = (int)block / drive->sect;
+               sect  = (int)block % drive->sect + 1;
                hwif->OUTB(sect, IDE_SECTOR_REG);
                head  = track % drive->head;
                cyl   = track / drive->head;
@@ -586,7 +590,7 @@ static ide_startstop_t lba_48_rw_disk(ide_drive_t *, struct request *, unsigned
  * using LBA if supported, or CHS otherwise, to address sectors.
  * It also takes care of issuing special DRIVE_CMDs.
  */
-static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
        BUG_ON(drive->blocked);
        if (!blk_fs_request(rq)) {
@@ -901,8 +905,8 @@ static u8 idedisk_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
                                }
                        }
                        if (HWGROUP(drive) && HWGROUP(drive)->rq)
-                               printk(", sector=%ld",
-                                       HWGROUP(drive)->rq->sector);
+                               printk(", sector=%llu",
+                                       (unsigned long long)HWGROUP(drive)->rq->sector);
                }
        }
 #endif /* FANCY_STATUS_DUMPS */
index 1b82fe4b22edc676065240e64fc3492dd221c2ef..bd94b83741c03e70670da93a300632a627e1499d 100644 (file)
@@ -1268,7 +1268,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
                return ide_stopped;
        }
        if (rq->flags & REQ_CMD) {
-               if ((rq->sector % floppy->bs_factor) ||
+               if (((long)rq->sector % floppy->bs_factor) ||
                    (rq->nr_sectors % floppy->bs_factor)) {
                        printk("%s: unsupported r/w request size\n",
                                drive->name);
index 1c202ec02ddbabfd5e4f1740683f3dabb28879be..550c3ae73e5a18402876529776055606567ad67a 100644 (file)
@@ -286,8 +286,8 @@ u8 taskfile_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
                                }
                        }
                        if (HWGROUP(drive)->rq)
-                               printk(", sector=%lu",
-                                       HWGROUP(drive)->rq->sector);
+                               printk(", sector=%llu",
+                                       (unsigned long long)HWGROUP(drive)->rq->sector);
                }
 media_out:
 #endif  /* FANCY_STATUS_DUMPS */
index d1e23cc829ba0615fca8f9d6e323f45b7eb95e49..13c58a36e550a377fd6e4bdb71bb32e9b4cef15b 100644 (file)
@@ -590,7 +590,7 @@ u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
                                        }
                                }
                                if (HWGROUP(drive) && HWGROUP(drive)->rq)
-                                       printk(", sector=%ld", HWGROUP(drive)->rq->sector);
+                                       printk(", sector=%llu", (unsigned long long)HWGROUP(drive)->rq->sector);
                        }
                }
 #endif /* FANCY_STATUS_DUMPS */
@@ -3270,7 +3270,7 @@ static int default_flushcache (ide_drive_t *drive)
        return 0;
 }
 
-static ide_startstop_t default_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t default_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
 {
        ide_end_request(drive, 0, 0);
        return ide_stopped;
index 8a790703b67cbd39049b578a015fb947d18c744d..b7c2f3213ccb58f72535a46ed7a8067722d7cb0b 100644 (file)
@@ -487,7 +487,7 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
 /*
  *     idescsi_do_request is our request handling function.
  */
-static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 #if IDESCSI_DEBUG_LOG
        printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
index ee087560277931f718e2ff8e5a4306b8f3f94026..bbb87f0b41f883b746bbb935187f477dd5b61cff 100644 (file)
@@ -471,13 +471,12 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
        return res;
 }
 
-unsigned char *read_dev_sector(struct block_device *bdev, unsigned long n, Sector *p)
+unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
 {
        struct address_space *mapping = bdev->bd_inode->i_mapping;
-       int sect = PAGE_CACHE_SIZE / 512;
        struct page *page;
 
-       page = read_cache_page(mapping, n/sect,
+       page = read_cache_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)),
                        (filler_t *)mapping->a_ops->readpage, NULL);
        if (!IS_ERR(page)) {
                wait_on_page_locked(page);
@@ -486,7 +485,7 @@ unsigned char *read_dev_sector(struct block_device *bdev, unsigned long n, Secto
                if (PageError(page))
                        goto fail;
                p->v = page;
-               return (unsigned char *)page_address(page) + 512 * (n % sect);
+               return (unsigned char *)page_address(page) +  ((n & ((1 << (PAGE_CACHE_SHIFT - 9)) - 1)) << 9);
 fail:
                page_cache_release(page);
        }
index 8598a571b76c0f553b82b1f416a14d6a30bce054..0be95725e097d4ecb542683b4806e5b37669332e 100644 (file)
@@ -5,14 +5,13 @@
  * add_gd_partition adds a partitions details to the devices partition
  * description.
  */
-
 enum { MAX_PART = 256 };
 
 struct parsed_partitions {
        char name[40];
        struct {
-               unsigned long from;
-               unsigned long size;
+               sector_t from;
+               sector_t size;
                int flags;
        } parts[MAX_PART];
        int next;
@@ -20,7 +19,7 @@ struct parsed_partitions {
 };
 
 static inline void
-put_partition(struct parsed_partitions *p, int n, int from, int size)
+put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size)
 {
        if (n < p->limit) {
                p->parts[n].from = from;
index 9ea7b652237b17f2652ca906a48f0421c2311957..4929d743683d8b3902294f0eb5a504b92d68ab6c 100644 (file)
@@ -37,7 +37,7 @@ struct request {
        int errors;
        sector_t sector;
        unsigned long nr_sectors;
-       unsigned long hard_sector;      /* the hard_* are block layer
+       sector_t hard_sector;           /* the hard_* are block layer
                                         * internals, no driver should
                                         * touch them
                                         */
@@ -394,13 +394,29 @@ extern inline unsigned int block_size(struct block_device *bdev)
 
 typedef struct {struct page *v;} Sector;
 
-unsigned char *read_dev_sector(struct block_device *, unsigned long, Sector *);
+unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *);
 
 static inline void put_dev_sector(Sector p)
 {
        page_cache_release(p.v);
 }
 
+#ifdef CONFIG_LBD
+# include <asm/div64.h>
+# define sector_div(a, b) do_div(a, b)
+#else
+# define sector_div(n, b)( \
+{ \
+       int _res; \
+       _res = (n) % (b); \
+       (n) /= (b); \
+       _res; \
+} \
+)
+#endif 
+
+
 extern atomic_t nr_iowait_tasks;
 void io_schedule(void);
 void io_schedule_timeout(long timeout);
index 3c7d1c358f5bf9a67ac0f8fc6c242aa1cbafef9f..62781b452fe95c9b0d25befb62bf986cdbb584a3 100644 (file)
@@ -59,8 +59,8 @@ struct partition {
 #  include <linux/devfs_fs_kernel.h>
 
 struct hd_struct {
-       unsigned long start_sect;
-       unsigned long nr_sects;
+       sector_t start_sect;
+       sector_t nr_sects;
        devfs_handle_t de;              /* primary (master) devfs entry  */
        struct device hd_driverfs_dev;  /* support driverfs hiearchy     */
 };
@@ -95,7 +95,7 @@ extern void add_disk(struct gendisk *disk);
 extern void del_gendisk(struct gendisk *gp);
 extern void unlink_gendisk(struct gendisk *gp);
 extern struct gendisk *get_gendisk(dev_t dev, int *part);
-static inline unsigned long get_start_sect(struct block_device *bdev)
+static inline sector_t get_start_sect(struct block_device *bdev)
 {
        return bdev->bd_offset;
 }
index dccb454552b3534341ca61b6a409fd3ca57b6fa6..0655a585300f8c4d66bb29dcb99f41d9102c3757 100644 (file)
@@ -1183,7 +1183,7 @@ typedef struct ide_driver_s {
        int             (*suspend)(ide_drive_t *);
        int             (*resume)(ide_drive_t *);
        int             (*flushcache)(ide_drive_t *);
-       ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long);
+       ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
        int             (*end_request)(ide_drive_t *, int, int);
        u8              (*sense)(ide_drive_t *, const char *, u8);
        ide_startstop_t (*error)(ide_drive_t *, const char *, u8);