9a5eb4f0c5
- Depend on devel/libublio instead of fetching sources and integrating them. - Install symlink in /usr/sbin/mount_ntfs-3g, to allow using with 'mount -t ntfs-3g' and in /etc/fstab, after mounting /usr. - Change default UBLIO_BLOCKSIZE value to 262144. - Update pkg-message, with notes about the mount_ntfs-3g symlink, and about problems with many simultaneous operations (not ublio's problem, but incremented when used with a larger blocksize).
623 lines
15 KiB
C
623 lines
15 KiB
C
--- libntfs-3g/unix_io.c.orig Fri Jun 8 18:35:33 2007
|
|
+++ libntfs-3g/unix_io.c Wed Jul 11 17:55:03 2007
|
|
@@ -54,6 +54,22 @@
|
|
#include <linux/fd.h>
|
|
#endif
|
|
|
|
+/*
|
|
+ * The following build definitions are available:
|
|
+ * USE_ALIGNED_IO - All I/O is done by blocks.
|
|
+ * USE_UBLIO - Use the ublio user space cache library.
|
|
+ * USE_LOCK - Lock the device/file when mounted.
|
|
+ */
|
|
+
|
|
+#ifdef __FreeBSD__
|
|
+#include <sys/disk.h>
|
|
+#define USE_ALIGNED_IO 1
|
|
+#endif
|
|
+
|
|
+#if USE_UBLIO
|
|
+#include <sys/uio.h>
|
|
+#endif
|
|
+
|
|
#include "types.h"
|
|
#include "mst.h"
|
|
#include "debug.h"
|
|
@@ -61,13 +77,90 @@
|
|
#include "logging.h"
|
|
#include "misc.h"
|
|
|
|
-#define DEV_FD(dev) (*(int *)dev->d_private)
|
|
+#if USE_UBLIO
|
|
+#define UBLIO_USE_API 1
|
|
+#include "ublio.h"
|
|
+#define UBLIO_DEFAULT_ENABLE 1
|
|
+#define UBLIO_DEFAULT_BLOCKSIZE 262144
|
|
+#define UBLIO_DEFAULT_ITEMS 64
|
|
+#define UBLIO_DEFAULT_GRACE 32
|
|
+#define UBLIO_DEFAULT_SYNC_IO 0
|
|
+#endif
|
|
+
|
|
+#if USE_ALIGNED_IO
|
|
+#define RAW_IO_ALIGNED(dev, offset, count) \
|
|
+ (DEV_HANDLE(dev)->block_size == 0 || \
|
|
+ ((offset) % DEV_HANDLE(dev)->block_size == 0 && \
|
|
+ (count) % DEV_HANDLE(dev)->block_size == 0))
|
|
+#define RAW_IO_ALIGN(dev, offset) \
|
|
+ ((offset) / DEV_HANDLE(dev)->block_size * DEV_HANDLE(dev)->block_size)
|
|
+#define RAW_IO_MAX_SIZE (128 * 1024 * 1024)
|
|
+#endif
|
|
+
|
|
+struct unix_filehandle {
|
|
+ int fd;
|
|
+#if USE_ALIGNED_IO
|
|
+ s64 pos;
|
|
+ s32 block_size;
|
|
+ s64 media_size;
|
|
+#endif
|
|
+#if USE_UBLIO
|
|
+ ublio_filehandle_t ublio_fh;
|
|
+#endif
|
|
+};
|
|
+
|
|
+#define DEV_HANDLE(dev) ((struct unix_filehandle *)dev->d_private)
|
|
+#define DEV_FD(dev) (DEV_HANDLE(dev)->fd)
|
|
|
|
/* Define to nothing if not present on this system. */
|
|
#ifndef O_EXCL
|
|
# define O_EXCL 0
|
|
#endif
|
|
|
|
+#if USE_ALIGNED_IO
|
|
+/**
|
|
+ * Get block_size and media_size
|
|
+ */
|
|
+static int
|
|
+raw_io_get_size(struct ntfs_device *dev)
|
|
+{
|
|
+ int bs;
|
|
+ off_t ms;
|
|
+ struct stat sb;
|
|
+
|
|
+ if (fstat(DEV_FD(dev), &sb) < 0) {
|
|
+ ntfs_log_perror("Failed to stat '%s'", dev->d_name);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (S_ISREG(sb.st_mode)) {
|
|
+ DEV_HANDLE(dev)->media_size = sb.st_size;
|
|
+ ntfs_log_trace("%s: regular file (media_size %lld)\n",
|
|
+ dev->d_name, DEV_HANDLE(dev)->media_size);
|
|
+ if (getenv("FORCE_ALIGNED_IO"))
|
|
+ DEV_HANDLE(dev)->block_size = 512;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (ioctl(DEV_FD(dev), DIOCGSECTORSIZE, &bs) < 0) {
|
|
+ ntfs_log_perror("Failed to ioctl(DIOCGSECTORSIZE) '%s'",
|
|
+ dev->d_name);
|
|
+ return -1;
|
|
+ }
|
|
+ DEV_HANDLE(dev)->block_size = bs;
|
|
+ ntfs_log_trace("%s: block size %d\n", dev->d_name, bs);
|
|
+
|
|
+ if (ioctl(DEV_FD(dev), DIOCGMEDIASIZE, &ms) < 0) {
|
|
+ ntfs_log_perror("Failed to ioctl(DIOCGMEDIASIZE) '%s'",
|
|
+ dev->d_name);
|
|
+ return -1;
|
|
+ }
|
|
+ DEV_HANDLE(dev)->media_size = ms;
|
|
+ ntfs_log_trace("%s: media size %lld\n", dev->d_name, ms);
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
/**
|
|
* ntfs_device_unix_io_open - Open a device and lock it exclusively
|
|
* @dev:
|
|
@@ -79,9 +172,21 @@
|
|
*/
|
|
static int ntfs_device_unix_io_open(struct ntfs_device *dev, int flags)
|
|
{
|
|
+#if USE_ALIGNED_IO
|
|
+ size_t sectsize;
|
|
+#endif
|
|
+#if USE_LOCK
|
|
struct flock flk;
|
|
+#endif
|
|
struct stat sbuf;
|
|
- int err;
|
|
+ struct unix_filehandle *ufh;
|
|
+ int err = 0;
|
|
+ int is_special = 0;
|
|
+#if USE_UBLIO
|
|
+ struct ublio_param up;
|
|
+ int use_ublio = 0;
|
|
+ char *xenv, *xgarbage;
|
|
+#endif
|
|
|
|
if (NDevOpen(dev)) {
|
|
errno = EBUSY;
|
|
@@ -91,20 +196,28 @@
|
|
ntfs_log_perror("Failed to access '%s'", dev->d_name);
|
|
return -1;
|
|
}
|
|
- if (S_ISBLK(sbuf.st_mode))
|
|
- NDevSetBlock(dev);
|
|
+ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode))
|
|
+ is_special = 1;
|
|
|
|
- dev->d_private = ntfs_malloc(sizeof(int));
|
|
- if (!dev->d_private)
|
|
+ ufh = ntfs_malloc(sizeof(*ufh));
|
|
+ if (!ufh)
|
|
return -1;
|
|
+ dev->d_private = ufh;
|
|
+#if USE_ALIGNED_IO
|
|
+ ufh->fd = -1;
|
|
+ ufh->pos = 0;
|
|
+ ufh->block_size = 0;
|
|
+ ufh->media_size = 0;
|
|
+#endif
|
|
+
|
|
/*
|
|
* Open file for exclusive access if mounting r/w.
|
|
* Fuseblk takes care about block devices.
|
|
*/
|
|
- if (!NDevBlock(dev) && (flags & O_RDWR) == O_RDWR)
|
|
+ if (!is_special && (flags & O_RDWR) == O_RDWR)
|
|
flags |= O_EXCL;
|
|
- *(int*)dev->d_private = open(dev->d_name, flags);
|
|
- if (*(int*)dev->d_private == -1) {
|
|
+ ufh->fd = open(dev->d_name, flags);
|
|
+ if (ufh->fd == -1) {
|
|
err = errno;
|
|
goto err_out;
|
|
}
|
|
@@ -112,6 +225,37 @@
|
|
if ((flags & O_RDWR) != O_RDWR)
|
|
NDevSetReadOnly(dev);
|
|
|
|
+#if USE_UBLIO
|
|
+ ufh->ublio_fh = NULL;
|
|
+ if ((xenv = getenv("NTFS_USE_UBLIO")) &&
|
|
+ (xenv[0] == '0' || xenv[0] == '1') && xenv[1] == '\0')
|
|
+ use_ublio = (xenv[0] == '1');
|
|
+ else
|
|
+ use_ublio = UBLIO_DEFAULT_ENABLE;
|
|
+ if ((xenv = getenv("UBLIO_BLOCKSIZE")))
|
|
+ up.up_blocksize = strtoul(xenv, &xgarbage, 10);
|
|
+ if (!xenv || *xgarbage != '\0')
|
|
+ up.up_blocksize = UBLIO_DEFAULT_BLOCKSIZE;
|
|
+ if ((xenv = getenv("UBLIO_ITEMS")))
|
|
+ up.up_items = strtoul(xenv, &xgarbage, 10);
|
|
+ if (!xenv || *xgarbage != '\0')
|
|
+ up.up_items = UBLIO_DEFAULT_ITEMS;
|
|
+ if ((xenv = getenv("UBLIO_GRACE")))
|
|
+ up.up_grace = strtoul(xenv, &xgarbage, 10);
|
|
+ if (!xenv || *xgarbage != '\0')
|
|
+ up.up_grace = UBLIO_DEFAULT_GRACE;
|
|
+ if ((xenv = getenv("UBLIO_SYNC_IO")) &&
|
|
+ (xenv[0] == '0' || xenv[0] == '1') && xenv[1] == '\0')
|
|
+ up.up_sync_io = (xenv[0] == '1');
|
|
+ else
|
|
+ up.up_sync_io = UBLIO_DEFAULT_SYNC_IO;
|
|
+ up.up_priv = &ufh->fd;
|
|
+ up.up_pread = NULL;
|
|
+ up.up_preadv = NULL;
|
|
+ up.up_pwrite = NULL;
|
|
+ up.up_pwritev = NULL;
|
|
+#endif
|
|
+#if USE_LOCK
|
|
memset(&flk, 0, sizeof(flk));
|
|
if (NDevReadOnly(dev))
|
|
flk.l_type = F_RDLCK;
|
|
@@ -119,7 +263,21 @@
|
|
flk.l_type = F_WRLCK;
|
|
flk.l_whence = SEEK_SET;
|
|
flk.l_start = flk.l_len = 0LL;
|
|
- if (fcntl(DEV_FD(dev), F_SETLK, &flk)) {
|
|
+#endif
|
|
+#if USE_ALIGNED_IO
|
|
+ if (raw_io_get_size(dev) < 0) {
|
|
+ err = errno;
|
|
+ close(DEV_FD(dev));
|
|
+ goto err_out;
|
|
+ }
|
|
+ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode))
|
|
+ NDevSetBlock(dev);
|
|
+#else
|
|
+ if (S_ISBLK(sbuf.st_mode))
|
|
+ NDevSetBlock(dev);
|
|
+#endif /* USE_ALIGNED_IO */
|
|
+#if USE_LOCK
|
|
+ if (!NDevBlock(dev) && fcntl(DEV_FD(dev), F_SETLK, &flk)) {
|
|
err = errno;
|
|
ntfs_log_perror("Failed to %s lock '%s'", NDevReadOnly(dev) ?
|
|
"read" : "write", dev->d_name);
|
|
@@ -127,7 +285,16 @@
|
|
ntfs_log_perror("Failed to close '%s'", dev->d_name);
|
|
goto err_out;
|
|
}
|
|
-
|
|
+#endif
|
|
+#if USE_UBLIO
|
|
+ if (use_ublio) {
|
|
+ ufh->ublio_fh = ublio_open(&up);
|
|
+ if (!ufh->ublio_fh) {
|
|
+ close(DEV_FD(dev));
|
|
+ goto err_out;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
NDevSetOpen(dev);
|
|
return 0;
|
|
err_out:
|
|
@@ -147,7 +314,10 @@
|
|
*/
|
|
static int ntfs_device_unix_io_close(struct ntfs_device *dev)
|
|
{
|
|
+ /* XXX no error if fysnc, fcntl (ublio_close) fails? */
|
|
+#if USE_LOCK
|
|
struct flock flk;
|
|
+#endif
|
|
|
|
if (!NDevOpen(dev)) {
|
|
errno = EBADF;
|
|
@@ -160,12 +330,18 @@
|
|
return -1;
|
|
}
|
|
|
|
+#if USE_LOCK
|
|
memset(&flk, 0, sizeof(flk));
|
|
flk.l_type = F_UNLCK;
|
|
flk.l_whence = SEEK_SET;
|
|
flk.l_start = flk.l_len = 0LL;
|
|
- if (fcntl(DEV_FD(dev), F_SETLK, &flk))
|
|
+ if (!NDevBlock(dev) && fcntl(DEV_FD(dev), F_SETLK, &flk))
|
|
ntfs_log_perror("Could not unlock %s", dev->d_name);
|
|
+#endif
|
|
+#if USE_UBLIO
|
|
+ if (DEV_HANDLE(dev)->ublio_fh)
|
|
+ ublio_close(DEV_HANDLE(dev)->ublio_fh);
|
|
+#endif
|
|
if (close(DEV_FD(dev))) {
|
|
ntfs_log_perror("Failed to close device %s", dev->d_name);
|
|
return -1;
|
|
@@ -189,9 +365,234 @@
|
|
static s64 ntfs_device_unix_io_seek(struct ntfs_device *dev, s64 offset,
|
|
int whence)
|
|
{
|
|
+#if USE_ALIGNED_IO
|
|
+ s64 abs_pos;
|
|
+
|
|
+ ntfs_log_trace("seek offset = 0x%llx, whence = %d.\n", offset, whence);
|
|
+ switch (whence) {
|
|
+ case SEEK_SET:
|
|
+ abs_pos = offset;
|
|
+ break;
|
|
+
|
|
+ case SEEK_CUR:
|
|
+ abs_pos = DEV_HANDLE(dev)->pos + offset;
|
|
+ break;
|
|
+
|
|
+ case SEEK_END:
|
|
+ abs_pos = DEV_HANDLE(dev)->media_size + offset;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ ntfs_log_trace("Wrong mode %d.\n", whence);
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (abs_pos < 0 || abs_pos > DEV_HANDLE(dev)->media_size) {
|
|
+ ntfs_log_trace("Seeking outsize seekable area.\n");
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+ DEV_HANDLE(dev)->pos = abs_pos;
|
|
+ return abs_pos;
|
|
+#else
|
|
return lseek(DEV_FD(dev), offset, whence);
|
|
+#endif
|
|
}
|
|
|
|
+#if USE_ALIGNED_IO
|
|
+
|
|
+#if USE_UBLIO
|
|
+#define pread_wrap(fd, buf, count, off) \
|
|
+ (DEV_HANDLE(fd)->ublio_fh ? \
|
|
+ ublio_pread(DEV_HANDLE(fd)->ublio_fh, buf, count, off) : \
|
|
+ pread(DEV_FD(fd), buf, count, off))
|
|
+#define pwrite_wrap(fd, buf, count, off) \
|
|
+ (DEV_HANDLE(fd)->ublio_fh ? \
|
|
+ ublio_pwrite(DEV_HANDLE(fd)->ublio_fh, buf, count, off) : \
|
|
+ pwrite(DEV_FD(fd), buf, count, off))
|
|
+#else
|
|
+#define pread_wrap(fd, buf, count, off) \
|
|
+ pread(DEV_FD(fd), buf, count, off)
|
|
+#define pwrite_wrap(fd, buf, count, off) \
|
|
+ pwrite(DEV_FD(fd), buf, count, off)
|
|
+#endif
|
|
+
|
|
+/**
|
|
+ * aligned_pread - Perform an aligned positioned read from the device
|
|
+ */
|
|
+static s64 aligned_pread(struct ntfs_device *dev, void *buf, s64 count, s64 offset)
|
|
+{
|
|
+ s64 start, start_aligned;
|
|
+ s64 end, end_aligned;
|
|
+ size_t count_aligned;
|
|
+ char *buf_aligned;
|
|
+ ssize_t nr;
|
|
+
|
|
+ /* short-circuit for regular files */
|
|
+ start = offset;
|
|
+ if (count > RAW_IO_MAX_SIZE)
|
|
+ count = RAW_IO_MAX_SIZE;
|
|
+ if (RAW_IO_ALIGNED(dev, start, count))
|
|
+ return pread_wrap(dev, buf, count, start);
|
|
+
|
|
+ /*
|
|
+ * +- start_aligned +- end_aligned
|
|
+ * | |
|
|
+ * | +- start +- end |
|
|
+ * v v v v
|
|
+ * |----------|----------|----------|
|
|
+ * ^ ^
|
|
+ * +----- count ------+
|
|
+ * ^ ^
|
|
+ * +-------- count_aligned ---------+
|
|
+ */
|
|
+ start_aligned = RAW_IO_ALIGN(dev, start);
|
|
+ end = start + count;
|
|
+ end_aligned = RAW_IO_ALIGN(dev, end) +
|
|
+ (RAW_IO_ALIGNED(dev, end, 0) ? 0 : DEV_HANDLE(dev)->block_size);
|
|
+ count_aligned = end_aligned - start_aligned;
|
|
+ ntfs_log_trace(
|
|
+ "%s: count = 0x%llx/0x%x, start = 0x%llx/0x%llx, end = 0x%llx/0x%llx\n",
|
|
+ dev->d_name, count, count_aligned,
|
|
+ start, start_aligned, end, end_aligned);
|
|
+
|
|
+ /* allocate buffer */
|
|
+ buf_aligned = ntfs_malloc(count_aligned);
|
|
+ if (buf_aligned == NULL) {
|
|
+ ntfs_log_trace("ntfs_malloc(%d) failed\n", count_aligned);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* read aligned data */
|
|
+ nr = pread_wrap(dev, buf_aligned, count_aligned, start_aligned);
|
|
+ if (nr == 0)
|
|
+ return 0;
|
|
+ if (nr < 0 || nr < start - start_aligned) {
|
|
+ free(buf_aligned);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* copy out */
|
|
+ memcpy(buf, buf_aligned + (start - start_aligned), count);
|
|
+ free(buf_aligned);
|
|
+
|
|
+ nr -= start - start_aligned;
|
|
+ if (nr > count)
|
|
+ nr = count;
|
|
+ return nr;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * aligned_pwrite - Perform an aligned positioned write from the device
|
|
+ */
|
|
+static s64 aligned_pwrite(struct ntfs_device *dev, void *buf, s64 count, s64 offset)
|
|
+{
|
|
+ s64 start, start_aligned;
|
|
+ s64 end, end_aligned;
|
|
+ size_t count_aligned;
|
|
+ char *buf_aligned;
|
|
+ ssize_t nw;
|
|
+
|
|
+ if (NDevReadOnly(dev)) {
|
|
+ errno = EROFS;
|
|
+ return -1;
|
|
+ }
|
|
+ NDevSetDirty(dev);
|
|
+
|
|
+ /* short-circuit for regular files */
|
|
+ start = offset;
|
|
+ if (count > RAW_IO_MAX_SIZE)
|
|
+ count = RAW_IO_MAX_SIZE;
|
|
+ if (RAW_IO_ALIGNED(dev, start, count))
|
|
+ return pwrite_wrap(dev, buf, count, start);
|
|
+
|
|
+ /*
|
|
+ * +- start_aligned +- end_aligned
|
|
+ * | |
|
|
+ * | +- start +- end |
|
|
+ * v v v v
|
|
+ * |----------|----------|----------|
|
|
+ * ^ ^
|
|
+ * +----- count ------+
|
|
+ * ^ ^
|
|
+ * +-------- count_aligned ---------+
|
|
+ */
|
|
+ start_aligned = RAW_IO_ALIGN(dev, start);
|
|
+ end = start + count;
|
|
+ end_aligned = RAW_IO_ALIGN(dev, end) +
|
|
+ (RAW_IO_ALIGNED(dev, end, 0) ? 0 : DEV_HANDLE(dev)->block_size);
|
|
+ count_aligned = end_aligned - start_aligned;
|
|
+ ntfs_log_trace(
|
|
+ "%s: count = 0x%llx/0x%x, start = 0x%llx/0x%llx, end = 0x%llx/0x%llx\n",
|
|
+ dev->d_name, count, count_aligned,
|
|
+ start, start_aligned, end, end_aligned);
|
|
+
|
|
+ /* allocate buffer */
|
|
+ buf_aligned = ntfs_malloc(count_aligned);
|
|
+ if (buf_aligned == NULL) {
|
|
+ ntfs_log_trace("ntfs_malloc(%d) failed\n", count_aligned);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* read aligned lead-in */
|
|
+ if (pread_wrap(dev, buf_aligned, DEV_HANDLE(dev)->block_size, start_aligned) != DEV_HANDLE(dev)->block_size) {
|
|
+ ntfs_log_trace("read lead-in failed\n");
|
|
+ free(buf_aligned);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* read aligned lead-out */
|
|
+ if (end != end_aligned && count_aligned > DEV_HANDLE(dev)->block_size) {
|
|
+ if (pread_wrap(dev, buf_aligned + count_aligned - DEV_HANDLE(dev)->block_size, DEV_HANDLE(dev)->block_size, end_aligned - DEV_HANDLE(dev)->block_size) != DEV_HANDLE(dev)->block_size) {
|
|
+ ntfs_log_trace("read lead-out failed\n");
|
|
+ free(buf_aligned);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* copy data to write */
|
|
+ memcpy(buf_aligned + (start - start_aligned), buf, count);
|
|
+
|
|
+ /* write aligned data */
|
|
+ nw = pwrite_wrap(dev, buf_aligned, count_aligned, start_aligned);
|
|
+ free(buf_aligned);
|
|
+ if (nw < 0 || nw < start - start_aligned)
|
|
+ return -1;
|
|
+
|
|
+ nw -= start - start_aligned;
|
|
+ if (nw > count)
|
|
+ nw = count;
|
|
+ return nw;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * aligned_read - Perform an aligned read from the device
|
|
+ */
|
|
+static s64 aligned_read(struct ntfs_device *dev, void *buf, s64 count)
|
|
+{
|
|
+ s64 nr = aligned_pread(dev, buf, count, DEV_HANDLE(dev)->pos);
|
|
+ if (nr > 0)
|
|
+ DEV_HANDLE(dev)->pos += nr;
|
|
+ return nr;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * aligned_write - Perform an aligned read from the device
|
|
+ */
|
|
+static s64 aligned_write(struct ntfs_device *dev, void *buf, s64 count)
|
|
+{
|
|
+ s64 nw = aligned_pwrite(dev, buf, count, DEV_HANDLE(dev)->pos);
|
|
+ if (nw > 0)
|
|
+ DEV_HANDLE(dev)->pos += nw;
|
|
+ return nw;
|
|
+}
|
|
+
|
|
+#undef ublio_pwrite
|
|
+#undef ublio_pread
|
|
+
|
|
+#endif
|
|
+
|
|
/**
|
|
* ntfs_device_unix_io_read - Read from the device, from the current location
|
|
* @dev:
|
|
@@ -205,6 +606,29 @@
|
|
static s64 ntfs_device_unix_io_read(struct ntfs_device *dev, void *buf,
|
|
s64 count)
|
|
{
|
|
+#if USE_ALIGNED_IO
|
|
+ return aligned_read(dev, buf, count);
|
|
+#elif USE_UBLIO
|
|
+ if (DEV_HANDLE(dev)->ublio_fh) {
|
|
+ off_t offset;
|
|
+ ssize_t res;
|
|
+
|
|
+ offset = lseek(DEV_FD(dev), 0, SEEK_CUR);
|
|
+ if (offset == -1)
|
|
+ return -1;
|
|
+
|
|
+ res = ublio_pread(DEV_HANDLE(dev)->ublio_fh, buf, count,
|
|
+ offset);
|
|
+ if (res == -1)
|
|
+ return -1;
|
|
+
|
|
+ if (lseek(DEV_FD(dev), res, SEEK_CUR) == -1)
|
|
+ return -1;
|
|
+
|
|
+ return res;
|
|
+ }
|
|
+#endif
|
|
+
|
|
return read(DEV_FD(dev), buf, count);
|
|
}
|
|
|
|
@@ -226,6 +650,28 @@
|
|
return -1;
|
|
}
|
|
NDevSetDirty(dev);
|
|
+#if USE_ALIGNED_IO
|
|
+ return aligned_write(dev, buf, count);
|
|
+#elif USE_UBLIO
|
|
+ if (DEV_HANDLE(dev)->ublio_fh)
|
|
+ off_t offset;
|
|
+ ssize_t res;
|
|
+
|
|
+ offset = lseek(DEV_FD(dev), 0, SEEK_CUR);
|
|
+ if (offset == -1)
|
|
+ return -1;
|
|
+
|
|
+ res = ublio_pwrite(DEV_HANDLE(dev)->ublio_fh, (void *)buf,
|
|
+ count, offset);
|
|
+ if (res == -1)
|
|
+ return -1;
|
|
+
|
|
+ if (lseek(DEV_FD(dev), res, SEEK_CUR) == -1)
|
|
+ return -1;
|
|
+
|
|
+ return res;
|
|
+ }
|
|
+#endif
|
|
return write(DEV_FD(dev), buf, count);
|
|
}
|
|
|
|
@@ -243,6 +689,13 @@
|
|
static s64 ntfs_device_unix_io_pread(struct ntfs_device *dev, void *buf,
|
|
s64 count, s64 offset)
|
|
{
|
|
+#if USE_ALIGNED_IO
|
|
+ return aligned_pread(dev, buf, count, offset);
|
|
+#elif USE_UBLIO
|
|
+ if (DEV_HANDLE(dev)->ublio_fh)
|
|
+ return ublio_pread(DEV_HANDLE(dev)->ublio_fh, buf, count,
|
|
+ offset);
|
|
+#endif
|
|
return pread(DEV_FD(dev), buf, count, offset);
|
|
}
|
|
|
|
@@ -265,6 +718,13 @@
|
|
return -1;
|
|
}
|
|
NDevSetDirty(dev);
|
|
+#if USE_ALIGNED_IO
|
|
+ return aligned_pwrite(dev, buf, count, offset);
|
|
+#elif USE_UBLIO
|
|
+ if (DEV_HANDLE(dev)->ublio_fh)
|
|
+ return ublio_pwrite(DEV_HANDLE(dev)->ublio_fh, (void *)buf,
|
|
+ count, offset);
|
|
+#endif
|
|
return pwrite(DEV_FD(dev), buf, count, offset);
|
|
}
|
|
|
|
@@ -281,7 +741,14 @@
|
|
int res = 0;
|
|
|
|
if (!NDevReadOnly(dev)) {
|
|
+#if USE_UBLIO
|
|
+ if (DEV_HANDLE(dev)->ublio_fh)
|
|
+ res = ublio_fsync(DEV_HANDLE(dev)->ublio_fh);
|
|
+ if (!DEV_HANDLE(dev)->ublio_fh || !res)
|
|
+ res = fsync(DEV_FD(dev));
|
|
+#else
|
|
res = fsync(DEV_FD(dev));
|
|
+#endif
|
|
if (res)
|
|
ntfs_log_perror("Failed to sync device %s", dev->d_name);
|
|
else
|