On Tue, Jan 27, 2009 at 08:26:53AM +1100, vincent.mcint...@csiro.au wrote: > umm - can't see it. I checked the bug as well. Could you resend please? > The 65d108f.diff patch does not apply cleanly. Attached now. -- Guido
>From d0e2a9285f0fa787c5de8ab82e8d9e075ce24d95 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Guido=20G=C3=BCnther?= <a...@sigxcpu.org> Date: Fri, 23 Jan 2009 17:19:59 +0100 Subject: [PATCH] [kpartx] use uint64_t to account slices start/size
And thus support >2TB partitioned devices. Redhat patch, pushed by Gerald Nowitzky. --- kpartx/devmapper.c | 4 +++- kpartx/devmapper.h | 4 ++-- kpartx/gpt.c | 35 ++++++++++++++++++++++------------- kpartx/kpartx.c | 25 +++++++++++++------------ kpartx/kpartx.h | 6 ++++-- 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c index 6e3e198..91070e5 100644 --- a/kpartx/devmapper.c +++ b/kpartx/devmapper.c @@ -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; diff --git a/kpartx/devmapper.h b/kpartx/devmapper.h index ccdbead..2bd27d2 100644 --- a/kpartx/devmapper.h +++ b/kpartx/devmapper.h @@ -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); diff --git a/kpartx/gpt.c b/kpartx/gpt.c index dc846ca..047a829 100644 --- a/kpartx/gpt.c +++ b/kpartx/gpt.c @@ -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 @@ -50,10 +51,18 @@ # 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, §ors); - 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) { diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c index f859bd3..54a628e 100644 --- a/kpartx/kpartx.c +++ b/kpartx/kpartx.c @@ -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> @@ -355,16 +356,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) @@ -376,9 +377,9 @@ main(int argc, char **argv){ slices[j].minor = m++; start = slices[j].start - slices[k].start; - printf("%s%s%d : 0 %lu %s%s%d %lu\n", + printf("%s%s%d : 0 %" PRIu64 " %s%s%d %" PRIu64 "\n", mapname, delim, j+1, - (unsigned long) slices[j].size, + slices[j].size, mapname, delim, k, start); c--; } @@ -437,8 +438,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); } @@ -457,7 +458,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); @@ -466,7 +467,7 @@ main(int argc, char **argv){ 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) @@ -493,7 +494,7 @@ main(int argc, char **argv){ strip_slash(partname); start = slices[j].start - slices[k].start; - if (safe_sprintf(params, "%d:%d %lu", + if (safe_sprintf(params, "%d:%d %" PRIu64, slices[k].major, slices[k].minor, start)) { @@ -515,7 +516,7 @@ main(int argc, char **argv){ &slices[j].minor); if (verbose) - printf("add map %s (%d:%d): 0 %lu %s\n", + printf("add map %s (%d:%d): 0 %" PRIu64 " %s\n", partname, slices[j].major, slices[j].minor, diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h index 9b3aeca..43ae3f8 100644 --- a/kpartx/kpartx.h +++ b/kpartx/kpartx.h @@ -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; -- 1.6.0.6