[kpartx] use uint64_t to account slices start/size
authorChristophe Varoqui <christophe.varoqui@free.fr>
Wed, 10 Oct 2007 21:13:31 +0000 (23:13 +0200)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Wed, 10 Oct 2007 21:13:31 +0000 (23:13 +0200)
And thus support >2TB partitioned devices.
Redhat patch, pushed by Gerald Nowitzky.

kpartx/devmapper.c
kpartx/devmapper.h
kpartx/gpt.c
kpartx/kpartx.c
kpartx/kpartx.h

index 3e973aa..893d6dd 100644 (file)
@@ -4,10 +4,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 #include <libdevmapper.h>
 #include <ctype.h>
 #include <linux/kdev_t.h>
 #include <errno.h>
+#include "devmapper.h"
 
 #define UUID_PREFIX "part%d-"
 #define MAX_PREFIX_LEN 8
@@ -72,7 +74,7 @@ dm_simplecmd (int task, const char *name) {
 
 extern int
 dm_addmap (int task, const char *name, const char *target,
-          const char *params, unsigned long size, const char *uuid, int part) {
+          const char *params, uint64_t size, const char *uuid, int part) {
        int r = 0;
        struct dm_task *dmt;
        char *prefixed_uuid = NULL;
index ccdbead..2bd27d2 100644 (file)
@@ -1,7 +1,7 @@
 int dm_prereq (char *, int, int, int);
 int dm_simplecmd (int, const char *);
-int dm_addmap (int, const char *, const char *, const char *, unsigned long,
-              char *, int);
+int dm_addmap (int, const char *, const char *, const char *, uint64_t,
+              const char *, int);
 int dm_map_present (char *);
 char * dm_mapname(int major, int minor);
 dev_t dm_get_first_dep(char *devname);
index dc846ca..047a829 100644 (file)
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <endian.h>
 #include <byteswap.h>
+#include <linux/fs.h>
 #include "crc32.h"
 
 #if BYTE_ORDER == LITTLE_ENDIAN
 #  define __cpu_to_le32(x) bswap_32(x)
 #endif
 
+#ifndef BLKGETLASTSECT
 #define BLKGETLASTSECT  _IO(0x12,108)   /* get last sector of block device */
+#endif
+#ifndef BLKGETSIZE
 #define BLKGETSIZE _IO(0x12,96)                /* return device size */
+#endif
+#ifndef BLKSSZGET
 #define BLKSSZGET  _IO(0x12,104)       /* get block device sector size */
+#endif
+#ifndef BLKGETSIZE64
 #define BLKGETSIZE64 _IOR(0x12,114,sizeof(uint64_t))   /* return device size in bytes (u64 *arg) */
+#endif
 
 struct blkdev_ioctl_param {
         unsigned int block;
@@ -143,20 +152,14 @@ get_sector_size(int filedes)
 static uint64_t
 _get_num_sectors(int filedes)
 {
-       unsigned long sectors=0;
        int rc;
-#if 0
-        uint64_t bytes=0;
+       uint64_t bytes=0;
 
-       rc = ioctl(filedes, BLKGETSIZE64, &bytes);
+       rc = ioctl(filedes, BLKGETSIZE64, &bytes);
        if (!rc)
                return bytes / get_sector_size(filedes);
-#endif
-        rc = ioctl(filedes, BLKGETSIZE, &sectors);
-        if (rc)
-                return 0;
-        
-       return sectors;
+
+       return 0;
 }
 
 /************************************************************
@@ -193,7 +196,7 @@ last_lba(int filedes)
                sectors = 1;
        }
 
-       return sectors - 1;
+       return sectors ? sectors - 1 : 0;
 }
 
 
@@ -220,17 +223,22 @@ read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
 {
        int sector_size = get_sector_size(fd);
        off_t offset = lba * sector_size;
+       uint64_t lastlba;
         ssize_t bytesread;
 
        lseek(fd, offset, SEEK_SET);
        bytesread = read(fd, buffer, bytes);
 
+       lastlba = last_lba(fd);
+       if (!lastlba)
+               return bytesread;
+
         /* Kludge.  This is necessary to read/write the last
            block of an odd-sized disk, until Linux 2.5.x kernel fixes.
            This is only used by gpt.c, and only to read
            one sector, so we don't have to be fancy.
         */
-        if (!bytesread && !(last_lba(fd) & 1) && lba == last_lba(fd)) {
+        if (!bytesread && !(lastlba & 1) && lba == lastlba) {
                 bytesread = read_lastoddsector(fd, lba, buffer, bytes);
         }
         return bytesread;
@@ -505,7 +513,8 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
        if (!gpt || !ptes)
                return 0;
 
-       lastlba = last_lba(fd);
+       if (!(lastlba = last_lba(fd)))
+               return 0;
        good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA,
                                 &pgpt, &pptes);
         if (good_pgpt) {
index dbe2ee2..72ca81d 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <ctype.h>
@@ -366,16 +367,16 @@ main(int argc, char **argv){
 
                                slices[j].minor = m++;
 
-                               printf("%s%s%d : 0 %lu %s %lu\n",
+                               printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n",
                                       mapname, delim, j+1,
-                                      (unsigned long) slices[j].size, device,
-                                      (unsigned long) slices[j].start);
+                                      slices[j].size, device,
+                                      slices[j].start);
                        }
                        /* Loop to resolve contained slices */
                        d = c;
                        while (c) {
                                for (j = 0; j < n; j++) {
-                                       unsigned long start;
+                                       uint64_t start;
                                        int k = slices[j].container - 1;
 
                                        if (slices[j].size == 0)
@@ -387,9 +388,9 @@ main(int argc, char **argv){
                                        slices[j].minor = m++;
 
                                        start = slices[j].start - slices[k].start;
-                                       printf("%s%s%d : 0 %lu /dev/dm-%d %lu\n",
+                                       printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n",
                                               mapname, delim, j+1,
-                                              (unsigned long) slices[j].size,
+                                              slices[j].size,
                                               slices[k].minor, start);
                                        c--;
                                }
@@ -448,8 +449,8 @@ main(int argc, char **argv){
                                }
                                strip_slash(partname);
 
-                               if (safe_sprintf(params, "%s %lu", device,
-                                            (unsigned long)slices[j].start)) {
+                               if (safe_sprintf(params, "%s %" PRIu64 ,
+                                                device, slices[j].start)) {
                                        fprintf(stderr, "params too small\n");
                                        exit(1);
                                }
@@ -468,7 +469,7 @@ main(int argc, char **argv){
                                        &slices[j].minor);
 
                                if (verbose)
-                                       printf("add map %s (%d:%d): 0 %lu %s %s\n",
+                                       printf("add map %s (%d:%d): 0 %" PRIu64 " %s %s\n",
                                               partname, slices[j].major,
                                               slices[j].minor, slices[j].size,
                                               DM_TARGET, params);
@@ -502,10 +503,10 @@ main(int argc, char **argv){
                                        }
                                        strip_slash(partname);
 
-                                       if (safe_sprintf(params, "%d:%d %lu",
+                                       if (safe_sprintf(params, "%d:%d %" PRIu64,
                                                         slices[k].major,
                                                         slices[k].minor,
-                                                        (unsigned long)slices[j].start)) {
+                                                        slices[j].start)) {
                                                fprintf(stderr, "params too small\n");
                                                exit(1);
                                        }
@@ -524,7 +525,7 @@ main(int argc, char **argv){
                                                &slices[j].minor);
 
                                        if (verbose)
-                                               printf("add map %s : 0 %lu %s %s\n",
+                                               printf("add map %s : 0 %" PRIu64 " %s %s\n",
                                                       partname, slices[j].size,
                                                       DM_TARGET, params);
                                        c--;
index 9b3aeca..43ae3f8 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _KPARTX_H
 #define _KPARTX_H
 
+#include <stdint.h>
+
 /*
  * For each partition type there is a routine that takes
  * a block device and a range, and returns the list of
@@ -20,8 +22,8 @@
  * units: 512 byte sectors
  */
 struct slice {
-       unsigned long start;
-       unsigned long size;
+       uint64_t start;
+       uint64_t size;
        int container;
        int major;
        int minor;