|
Line 0
Link Here
|
|
|
1 |
# Revert 3959f7d to restore ublio support and add autoconf glue. |
| 2 |
|
| 3 |
diff --git README.md README.md |
| 4 |
index 60d5c71..81446a6 100644 |
| 5 |
--- README.md |
| 6 |
+++ README.md |
| 7 |
@@ -7,6 +7,7 @@ Supported operating systems: |
| 8 |
|
| 9 |
* GNU/Linux |
| 10 |
* Mac OS X 10.5 or later |
| 11 |
+* FreeBSD |
| 12 |
* OpenBSD |
| 13 |
|
| 14 |
Most GNU/Linux distributions already have fuse-exfat and exfat-utils in their repositories, so you can just install and use them. The next chapter describes how to compile them from source. |
| 15 |
diff --git configure.ac configure.ac |
| 16 |
index b45db3f..2bcda4b 100644 |
| 17 |
--- configure.ac |
| 18 |
+++ configure.ac |
| 19 |
@@ -31,6 +31,12 @@ AC_PROG_CC_C99 |
| 20 |
AC_PROG_RANLIB |
| 21 |
AM_PROG_AR |
| 22 |
AC_SYS_LARGEFILE |
| 23 |
+PKG_CHECK_MODULES([UBLIO], [libublio], [ |
| 24 |
+ CFLAGS="$CFLAGS $UBLIO_CFLAGS" |
| 25 |
+ LIBS="$LIBS $UBLIO_LIBS" |
| 26 |
+ AC_DEFINE([USE_UBLIO], [1], |
| 27 |
+ [Define if block devices are not supported.]) |
| 28 |
+], [:]) |
| 29 |
PKG_CHECK_MODULES([FUSE], [fuse]) |
| 30 |
AC_CONFIG_HEADERS([libexfat/config.h]) |
| 31 |
AC_CONFIG_FILES([ |
| 32 |
diff --git libexfat/io.c libexfat/io.c |
| 33 |
index 60f28e2..14c0151 100644 |
| 34 |
--- libexfat/io.c |
| 35 |
+++ libexfat/io.c |
| 36 |
@@ -37,12 +37,20 @@ |
| 37 |
#include <sys/ioctl.h> |
| 38 |
#endif |
| 39 |
#include <sys/mount.h> |
| 40 |
+#ifdef USE_UBLIO |
| 41 |
+#include <sys/uio.h> |
| 42 |
+#include <ublio.h> |
| 43 |
+#endif |
| 44 |
|
| 45 |
struct exfat_dev |
| 46 |
{ |
| 47 |
int fd; |
| 48 |
enum exfat_mode mode; |
| 49 |
off_t size; /* in bytes */ |
| 50 |
+#ifdef USE_UBLIO |
| 51 |
+ off_t pos; |
| 52 |
+ ublio_filehandle_t ufh; |
| 53 |
+#endif |
| 54 |
}; |
| 55 |
|
| 56 |
static int open_ro(const char* spec) |
| 57 |
@@ -74,6 +82,9 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) |
| 58 |
{ |
| 59 |
struct exfat_dev* dev; |
| 60 |
struct stat stbuf; |
| 61 |
+#ifdef USE_UBLIO |
| 62 |
+ struct ublio_param up; |
| 63 |
+#endif |
| 64 |
|
| 65 |
dev = malloc(sizeof(struct exfat_dev)); |
| 66 |
if (dev == NULL) |
| 67 |
@@ -211,6 +222,24 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) |
| 68 |
} |
| 69 |
} |
| 70 |
|
| 71 |
+#ifdef USE_UBLIO |
| 72 |
+ memset(&up, 0, sizeof(struct ublio_param)); |
| 73 |
+ up.up_blocksize = 256 * 1024; |
| 74 |
+ up.up_items = 64; |
| 75 |
+ up.up_grace = 32; |
| 76 |
+ up.up_priv = &dev->fd; |
| 77 |
+ |
| 78 |
+ dev->pos = 0; |
| 79 |
+ dev->ufh = ublio_open(&up); |
| 80 |
+ if (dev->ufh == NULL) |
| 81 |
+ { |
| 82 |
+ close(dev->fd); |
| 83 |
+ free(dev); |
| 84 |
+ exfat_error("failed to initialize ublio"); |
| 85 |
+ return NULL; |
| 86 |
+ } |
| 87 |
+#endif |
| 88 |
+ |
| 89 |
return dev; |
| 90 |
} |
| 91 |
|
| 92 |
@@ -218,6 +247,13 @@ int exfat_close(struct exfat_dev* dev) |
| 93 |
{ |
| 94 |
int rc = 0; |
| 95 |
|
| 96 |
+#ifdef USE_UBLIO |
| 97 |
+ if (ublio_close(dev->ufh) != 0) |
| 98 |
+ { |
| 99 |
+ exfat_error("failed to close ublio"); |
| 100 |
+ rc = -EIO; |
| 101 |
+ } |
| 102 |
+#endif |
| 103 |
if (close(dev->fd) != 0) |
| 104 |
{ |
| 105 |
exfat_error("failed to close device: %s", strerror(errno)); |
| 106 |
@@ -231,6 +267,13 @@ int exfat_fsync(struct exfat_dev* dev) |
| 107 |
{ |
| 108 |
int rc = 0; |
| 109 |
|
| 110 |
+#ifdef USE_UBLIO |
| 111 |
+ if (ublio_fsync(dev->ufh) != 0) |
| 112 |
+ { |
| 113 |
+ exfat_error("ublio fsync failed"); |
| 114 |
+ rc = -EIO; |
| 115 |
+ } |
| 116 |
+#endif |
| 117 |
if (fsync(dev->fd) != 0) |
| 118 |
{ |
| 119 |
exfat_error("fsync failed: %s", strerror(errno)); |
| 120 |
@@ -251,29 +294,56 @@ off_t exfat_get_size(const struct exfat_dev* dev) |
| 121 |
|
| 122 |
off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence) |
| 123 |
{ |
| 124 |
+#ifdef USE_UBLIO |
| 125 |
+ /* XXX SEEK_CUR will be handled incorrectly */ |
| 126 |
+ return dev->pos = lseek(dev->fd, offset, whence); |
| 127 |
+#else |
| 128 |
return lseek(dev->fd, offset, whence); |
| 129 |
+#endif |
| 130 |
} |
| 131 |
|
| 132 |
ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size) |
| 133 |
{ |
| 134 |
+#ifdef USE_UBLIO |
| 135 |
+ ssize_t result = ublio_pread(dev->ufh, buffer, size, dev->pos); |
| 136 |
+ if (result >= 0) |
| 137 |
+ dev->pos += size; |
| 138 |
+ return result; |
| 139 |
+#else |
| 140 |
return read(dev->fd, buffer, size); |
| 141 |
+#endif |
| 142 |
} |
| 143 |
|
| 144 |
ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size) |
| 145 |
{ |
| 146 |
+#ifdef USE_UBLIO |
| 147 |
+ ssize_t result = ublio_pwrite(dev->ufh, buffer, size, dev->pos); |
| 148 |
+ if (result >= 0) |
| 149 |
+ dev->pos += size; |
| 150 |
+ return result; |
| 151 |
+#else |
| 152 |
return write(dev->fd, buffer, size); |
| 153 |
+#endif |
| 154 |
} |
| 155 |
|
| 156 |
ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size, |
| 157 |
off_t offset) |
| 158 |
{ |
| 159 |
+#ifdef USE_UBLIO |
| 160 |
+ return ublio_pread(dev->ufh, buffer, size, offset); |
| 161 |
+#else |
| 162 |
return pread(dev->fd, buffer, size, offset); |
| 163 |
+#endif |
| 164 |
} |
| 165 |
|
| 166 |
ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size, |
| 167 |
off_t offset) |
| 168 |
{ |
| 169 |
+#ifdef USE_UBLIO |
| 170 |
+ return ublio_pwrite(dev->ufh, buffer, size, offset); |
| 171 |
+#else |
| 172 |
return pwrite(dev->fd, buffer, size, offset); |
| 173 |
+#endif |
| 174 |
} |
| 175 |
|
| 176 |
ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, |