From: resver Date: Wed, 12 Dec 2012 19:14:36 +0000 (+0000) Subject: OS X: correctly detect device size. X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-exfat.git;a=commitdiff_plain;h=6ae76abe8e51aa9d616fd859e66a2cfea1a3ae69 OS X: correctly detect device size. git-svn-id: http://exfat.googlecode.com/svn/trunk@307 60bc1c72-a15a-11de-b98f-4500b42dc123 --- diff --git a/libexfat/exfat.h b/libexfat/exfat.h index 03107d7..7eb1fa6 100644 --- a/libexfat/exfat.h +++ b/libexfat/exfat.h @@ -136,6 +136,7 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode); int exfat_close(struct exfat_dev* dev); int exfat_fsync(struct exfat_dev* dev); enum exfat_mode exfat_get_mode(const struct exfat_dev* dev); +off_t exfat_get_size(const struct exfat_dev* dev); off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence); ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size); ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size); diff --git a/libexfat/io.c b/libexfat/io.c index 0a04aa1..e9672fb 100644 --- a/libexfat/io.c +++ b/libexfat/io.c @@ -26,6 +26,9 @@ #include #include #include +#ifdef __APPLE__ +#include +#endif #ifdef USE_UBLIO #include #include @@ -39,6 +42,7 @@ struct exfat_dev { int fd; enum exfat_mode mode; + off_t size; /* in bytes */ #ifdef USE_UBLIO off_t pos; ublio_filehandle_t ufh; @@ -142,6 +146,42 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) return NULL; } +#ifdef __APPLE__ + if (S_ISBLK(stbuf.st_mode)) + { + uint32_t block_size = 0; + uint64_t blocks = 0; + + if (ioctl(dev->fd, DKIOCGETBLOCKSIZE, &block_size) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get block size"); + return NULL; + } + if (ioctl(dev->fd, DKIOCGETBLOCKCOUNT, &blocks) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get blocks count"); + return NULL; + } + dev->size = blocks * block_size; + } + else +#endif + { + /* works for Linux, FreeBSD, Solaris */ + dev->size = exfat_seek(dev, 0, SEEK_END); + if (dev->size <= 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get device size"); + return NULL; + } + } + #ifdef USE_UBLIO memset(&up, 0, sizeof(struct ublio_param)); up.up_blocksize = 256 * 1024; @@ -198,6 +238,11 @@ enum exfat_mode exfat_get_mode(const struct exfat_dev* dev) return dev->mode; } +off_t exfat_get_size(const struct exfat_dev* dev) +{ + return dev->size; +} + off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence) { #ifdef USE_UBLIO diff --git a/mkfs/main.c b/mkfs/main.c index b8ce63d..e842c71 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -96,14 +96,6 @@ int get_cluster_size(void) return get_sector_size() << get_spc_bits(); } -static off_t setup_volume_size(struct exfat_dev* dev) -{ - off_t size = exfat_seek(dev, 0, SEEK_END); - if (size == (off_t) -1) - exfat_error("failed to get volume size"); - return size; -} - static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size) { int i; @@ -166,10 +158,7 @@ static int setup(struct exfat_dev* dev, int sector_bits, int spc_bits, { param.sector_bits = sector_bits; param.first_sector = first_sector; - - param.volume_size = setup_volume_size(dev); - if (param.volume_size == (off_t) -1) - return 1; + param.volume_size = exfat_get_size(dev); param.spc_bits = setup_spc_bits(sector_bits, spc_bits, param.volume_size); if (param.spc_bits == -1)