From 245a6a5a280cb021faa54bbcb931415f3d182dd9 Mon Sep 17 00:00:00 2001 From: srs5694 <srs5694@users.sourceforge.net> Date: Tue, 19 Jan 2010 20:24:38 -0500 Subject: [PATCH] Fixed bug regarding disk size on FreeBSD when using disk images. This but doesn't affect disk files or non-FreeBSD platforms. --- gpt.h | 2 +- support.cc | 122 ++++++++++++++++++++++++++--------------------------- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/gpt.h b/gpt.h index 2dab928..1f780ee 100644 --- a/gpt.h +++ b/gpt.h @@ -16,7 +16,7 @@ #ifndef __GPTSTRUCTS #define __GPTSTRUCTS -#define GPTFDISK_VERSION "0.6.0" +#define GPTFDISK_VERSION "0.6.1-pre2" using namespace std; diff --git a/support.cc b/support.cc index c30f4e7..47ff438 100644 --- a/support.cc +++ b/support.cc @@ -510,67 +510,6 @@ void DiskSync(int fd) { #endif } // DiskSync() -/************************************************************************************** - * * - * Below functions are lifted from various sources, as documented in comments before * - * each one. * - * * - **************************************************************************************/ - -// The disksize function is taken from the Linux fdisk code and modified -// to work around a problem returning a uint64_t value on Mac OS. -uint64_t disksize(int fd, int *err) { - long sz; // Do not delete; needed for Linux - long long b; // Do not delete; needed for Linux - uint64_t sectors = 0; // size in sectors - off_t bytes = 0; // size in bytes - struct stat64 st; - - // Note to self: I recall testing a simplified version of - // this code, similar to what's in the __APPLE__ block, - // on Linux, but I had some problems. IIRC, it ran OK on 32-bit - // systems but not on 64-bit. Keep this in mind in case of - // 32/64-bit issues on MacOS.... -#ifdef __APPLE__ - *err = ioctl(fd, DKIOCGETBLOCKCOUNT, §ors); -#else -#ifdef __FreeBSD__ - *err = ioctl(fd, DIOCGMEDIASIZE, &sz); - b = GetBlockSize(fd); - sectors = sz / b; -#else - *err = ioctl(fd, BLKGETSIZE, &sz); - if (*err) { - sectors = sz = 0; - } // if - if ((errno == EFBIG) || (!*err)) { - *err = ioctl(fd, BLKGETSIZE64, &b); - if (*err || b == 0 || b == sz) - sectors = sz; - else - sectors = (b >> 9); - } // if - // Unintuitively, the above returns values in 512-byte blocks, no - // matter what the underlying device's block size. Correct for this.... - sectors /= (GetBlockSize(fd) / 512); -#endif -#endif - - // The above methods have failed (or it's a bum filename reference), - // so let's assume it's a regular file (a QEMU image, dd backup, or - // what have you) and see what stat() gives us.... - if (sectors == 0) { - if (fstat64(fd, &st) == 0) { - bytes = (uint64_t) st.st_size; - if ((bytes % UINT64_C(512)) != 0) - fprintf(stderr, "Warning: File size is not a multiple of 512 bytes!" - " Misbehavior is likely!\n\a"); - sectors = bytes / UINT64_C(512); - } // if - } // if - return sectors; -} // disksize() - // A variant on the standard read() function. Done to work around // limitations in FreeBSD concerning the matching of the sector // size with the number of bytes read @@ -637,3 +576,64 @@ int myWrite(int fd, char* buffer, int numBytes) { free(tempSpace); return retval; } // myRead() + +/************************************************************************************** + * * + * Below functions are lifted from various sources, as documented in comments before * + * each one. * + * * + **************************************************************************************/ + +// The disksize function is taken from the Linux fdisk code and modified +// to work around a problem returning a uint64_t value on Mac OS. +uint64_t disksize(int fd, int *err) { + long sz; // Do not delete; needed for Linux + long long b; // Do not delete; needed for Linux + uint64_t sectors = 0; // size in sectors + off_t bytes = 0; // size in bytes + struct stat64 st; + + // Note to self: I recall testing a simplified version of + // this code, similar to what's in the __APPLE__ block, + // on Linux, but I had some problems. IIRC, it ran OK on 32-bit + // systems but not on 64-bit. Keep this in mind in case of + // 32/64-bit issues on MacOS.... +#ifdef __APPLE__ + *err = ioctl(fd, DKIOCGETBLOCKCOUNT, §ors); +#else +#ifdef __FreeBSD__ + *err = ioctl(fd, DIOCGMEDIASIZE, &sz); + b = GetBlockSize(fd); + sectors = sz / b; +#else + *err = ioctl(fd, BLKGETSIZE, &sz); + if (*err) { + sectors = sz = 0; + } // if + if ((errno == EFBIG) || (!*err)) { + *err = ioctl(fd, BLKGETSIZE64, &b); + if (*err || b == 0 || b == sz) + sectors = sz; + else + sectors = (b >> 9); + } // if + // Unintuitively, the above returns values in 512-byte blocks, no + // matter what the underlying device's block size. Correct for this.... + sectors /= (GetBlockSize(fd) / 512); +#endif +#endif + + // The above methods have failed (or it's a bum filename reference), + // so let's assume it's a regular file (a QEMU image, dd backup, or + // what have you) and see what stat() gives us.... + if ((sectors == 0) || (*err == -1)) { + if (fstat64(fd, &st) == 0) { + bytes = (uint64_t) st.st_size; + if ((bytes % UINT64_C(512)) != 0) + fprintf(stderr, "Warning: File size is not a multiple of 512 bytes!" + " Misbehavior is likely!\n\a"); + sectors = bytes / UINT64_C(512); + } // if + } // if + return sectors; +} // disksize() -- GitLab