aboutsummaryrefslogtreecommitdiff
path: root/sysutils/ntfsprogs/files
diff options
context:
space:
mode:
authorAlejandro Pulver <alepulver@FreeBSD.org>2007-10-30 03:22:04 +0000
committerAlejandro Pulver <alepulver@FreeBSD.org>2007-10-30 03:22:04 +0000
commitcf9758e30f7959f1f1b7627500276d3eaf2990ae (patch)
tree82ca3b72ed42f5d8e9a9ad64ce4891d5142af653 /sysutils/ntfsprogs/files
parentc548b8970f62d05b33e404db5046067675baf74d (diff)
Notes
Diffstat (limited to 'sysutils/ntfsprogs/files')
-rw-r--r--sysutils/ntfsprogs/files/patch-libntfs-device.c56
-rw-r--r--sysutils/ntfsprogs/files/patch-libntfs-device_io.c14
-rw-r--r--sysutils/ntfsprogs/files/patch-libntfs-unix_io.c624
-rw-r--r--sysutils/ntfsprogs/files/patch-ntfsprogs-Makefile.in19
-rw-r--r--sysutils/ntfsprogs/files/pkg-message.in13
-rw-r--r--sysutils/ntfsprogs/files/unix_io_raw.c593
6 files changed, 712 insertions, 607 deletions
diff --git a/sysutils/ntfsprogs/files/patch-libntfs-device.c b/sysutils/ntfsprogs/files/patch-libntfs-device.c
new file mode 100644
index 000000000000..dfcc22a5eb05
--- /dev/null
+++ b/sysutils/ntfsprogs/files/patch-libntfs-device.c
@@ -0,0 +1,56 @@
+--- ./libntfs/device.c.orig Tue Jan 9 18:22:57 2007
++++ ./libntfs/device.c Mon Apr 30 13:40:54 2007
+@@ -63,6 +63,9 @@
+ #ifdef HAVE_LINUX_HDREG_H
+ #include <linux/hdreg.h>
+ #endif
++#ifdef __FreeBSD__
++#include <sys/disk.h>
++#endif
+
+ #include "types.h"
+ #include "mst.h"
+@@ -533,6 +536,17 @@
+ }
+ }
+ #endif
++#ifdef DIOCGMEDIASIZE
++ { off_t size;
++
++ if (dev->d_ops->ioctl(dev, DIOCGMEDIASIZE, &size) >= 0) {
++ ntfs_log_debug("DIOCGMEDIASIZE nr bytes = %llu (0x%llx)\n",
++ (unsigned long long)size,
++ (unsigned long long)size);
++ return (s64)size / block_size;
++ }
++ }
++#endif
+ /*
+ * We couldn't figure it out by using a specialized ioctl,
+ * so do binary search to find the size of the device.
+@@ -681,7 +695,24 @@
+ return sect_size;
+ }
+ }
+-#else
++#elif defined(DIOCGSECTORSIZE)
++ /*
++ * XXX On FreeBSD (where we have DIOCGSECTORSIZE) the low-level I/O
++ * system already knows the sector size, and doing an ioctl is needless.
++ * However, I don't know how to extract that information cleanly,
++ * without letting a bunch of platform specific #ifdef-s to sneak in.
++ * So now I rather just re-do the ioctl...
++ */
++ {
++ size_t sect_size = 0;
++
++ if (!dev->d_ops->ioctl(dev, DIOCGSECTORSIZE, &sect_size)) {
++ ntfs_log_debug("DIOCGSECTORSIZE sector size = %d bytes\n",
++ (int)sect_size);
++ return sect_size;
++ }
++ }
++#else
+ errno = EOPNOTSUPP;
+ #endif
+ return -1;
diff --git a/sysutils/ntfsprogs/files/patch-libntfs-device_io.c b/sysutils/ntfsprogs/files/patch-libntfs-device_io.c
deleted file mode 100644
index 13cf4a9e3991..000000000000
--- a/sysutils/ntfsprogs/files/patch-libntfs-device_io.c
+++ /dev/null
@@ -1,14 +0,0 @@
---- libntfs/device_io.c.orig Wed Dec 6 03:57:01 2006
-+++ libntfs/device_io.c Wed Dec 6 03:05:24 2006
-@@ -26,7 +26,11 @@
- #ifndef __CYGWIN32__
-
- /* Not on Cygwin; use standard Unix style low level device operations. */
-+#if defined(__FreeBSD__)
-+#include "unix_io_raw.c"
-+#else
- #include "unix_io.c"
-+#endif
-
- #else /* __CYGWIN32__ */
-
diff --git a/sysutils/ntfsprogs/files/patch-libntfs-unix_io.c b/sysutils/ntfsprogs/files/patch-libntfs-unix_io.c
new file mode 100644
index 000000000000..a31fd9b78deb
--- /dev/null
+++ b/sysutils/ntfsprogs/files/patch-libntfs-unix_io.c
@@ -0,0 +1,624 @@
+--- libntfs/unix_io.c.orig Fri Feb 3 23:42:42 2006
++++ libntfs/unix_io.c Mon Sep 10 17:56:18 2007
+@@ -54,19 +54,112 @@
+ #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"
+ #include "device.h"
+ #include "logging.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:
+@@ -78,30 +171,87 @@
+ */
+ 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;
+ return -1;
+ }
+- if (!(dev->d_private = malloc(sizeof(int))))
++
++ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode))
++ is_special = 1;
++
++ ufh = 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 the device/file obtaining the file descriptor for exclusive
+ * access (but only if mounting r/w).
+ */
+- if ((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;
+ }
+ /* Setup our read-only flag. */
+ 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
+ /* Acquire exclusive (mandatory) lock on the whole device. */
+ memset(&flk, 0, sizeof(flk));
+ if (NDevReadOnly(dev))
+@@ -110,7 +260,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_debug("ntfs_device_unix_io_open: Could not lock %s for %s\n",
+ dev->d_name, NDevReadOnly(dev) ? "reading" : "writing");
+@@ -119,6 +283,16 @@
+ "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
+ /* Determine if device is a block device or not, ignoring errors. */
+ if (!fstat(DEV_FD(dev), &sbuf) && S_ISBLK(sbuf.st_mode))
+ NDevSetBlock(dev);
+@@ -142,7 +316,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;
+@@ -150,14 +327,20 @@
+ }
+ if (NDevDirty(dev))
+ fsync(DEV_FD(dev));
++#if USE_LOCK
+ /* Release exclusive (mandatory) lock on the whole device. */
+ 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("ntfs_device_unix_io_close: Warning: 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
+ /* Close the file descriptor and clear our open flag. */
+ if (close(DEV_FD(dev)))
+ return -1;
+@@ -180,10 +363,235 @@
+ 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 = malloc(count_aligned);
++ if (buf_aligned == NULL) {
++ ntfs_log_trace("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 = malloc(count_aligned);
++ if (buf_aligned == NULL) {
++ ntfs_log_trace("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:
+ * @buf:
+@@ -196,6 +604,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);
+ }
+
+@@ -217,6 +648,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);
+ }
+
+@@ -234,6 +687,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 ntfs_pread(dev, offset, count, buf);
+ }
+
+@@ -256,6 +716,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 ntfs_pwrite(dev, offset, count, buf);
+ }
+
+@@ -269,8 +736,17 @@
+ */
+ static int ntfs_device_unix_io_sync(struct ntfs_device *dev)
+ {
++ int res;
++
+ if (!NDevReadOnly(dev) && NDevDirty(dev)) {
+- int res = fsync(DEV_FD(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)
+ NDevClearDirty(dev);
+ return res;
diff --git a/sysutils/ntfsprogs/files/patch-ntfsprogs-Makefile.in b/sysutils/ntfsprogs/files/patch-ntfsprogs-Makefile.in
new file mode 100644
index 000000000000..30d5a3d5d44c
--- /dev/null
+++ b/sysutils/ntfsprogs/files/patch-ntfsprogs-Makefile.in
@@ -0,0 +1,19 @@
+--- ntfsprogs/Makefile.in.orig Wed Jun 21 05:41:46 2006
++++ ntfsprogs/Makefile.in Mon Sep 10 15:47:08 2007
+@@ -914,13 +914,14 @@
+
+ install-exec-hook:
+ $(INSTALL) -d $(DESTDIR)/sbin
++ $(INSTALL) -d $(DESTDIR)/usr/sbin
+ $(LN_S) -f $(sbindir)/mkntfs $(DESTDIR)/sbin/mkfs.ntfs
+-@ENABLE_FUSE_MODULE_TRUE@ $(LN_S) -f $(bindir)/ntfsmount $(DESTDIR)/sbin/mount.ntfs-fuse
++@ENABLE_FUSE_MODULE_TRUE@ $(LN_S) -f $(bindir)/ntfsmount $(DESTDIR)/usr/sbin/mount_ntfs-fuse
+
+ install-data-hook:
+ $(INSTALL) -d $(DESTDIR)$(man8dir)
+ $(LN_S) -f mkntfs.8 $(DESTDIR)$(man8dir)/mkfs.ntfs.8
+-@ENABLE_FUSE_MODULE_TRUE@ $(LN_S) -f ntfsmount.8 $(DESTDIR)$(man8dir)/mount.ntfs-fuse.8
++@ENABLE_FUSE_MODULE_TRUE@ $(LN_S) -f ntfsmount.8 $(DESTDIR)$(man8dir)/mount_ntfs-fuse.8
+
+ uninstall-local:
+ $(RM) -f $(DESTDIR)/sbin/mkfs.ntfs
diff --git a/sysutils/ntfsprogs/files/pkg-message.in b/sysutils/ntfsprogs/files/pkg-message.in
new file mode 100644
index 000000000000..5ce938b93120
--- /dev/null
+++ b/sysutils/ntfsprogs/files/pkg-message.in
@@ -0,0 +1,13 @@
+==============================================================================
+
+If UBLIO (cache for improving performance) was enabled, see the following to
+know more about it: "ports/sysutils/fusefs-ntfs/files/pkg-message.in" (only
+the relevant parts).
+
+If FUSE (mount support) was enabled, note that there is no write capability
+and does not allow to browse directories with programs like the GTK+ file
+browser, Midnight Commander, etc. So for mounting it's better to use
+"sysutils/fusefs-ntfs". Note that the mount(8) filesystem type installed by
+this port is called "ntfs-fuse".
+
+==============================================================================
diff --git a/sysutils/ntfsprogs/files/unix_io_raw.c b/sysutils/ntfsprogs/files/unix_io_raw.c
deleted file mode 100644
index 5a2cccc7d2ab..000000000000
--- a/sysutils/ntfsprogs/files/unix_io_raw.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/**
- * unix_io.c - Unix style disk io functions. Originated from the Linux-NTFS project.
- *
- * Copyright (c) 2006 Max Khon
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (in the main directory of the NTFS-3G
- * distribution in the file COPYING); if not, write to the Free Software
- * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_LINUX_FD_H
-#include <linux/fd.h>
-#endif
-#include <sys/disk.h>
-
-#include "types.h"
-#include "mst.h"
-#include "debug.h"
-#include "device.h"
-#include "logging.h"
-
-typedef struct {
- int fd;
- s64 pos;
- s32 block_size;
- s64 media_size;
-} unix_raw_fd;
-
-#define DEV_FD(dev) (((unix_raw_fd *) dev->d_private))
-#define RAW_IO_ALIGNED(dev, offset, count) \
- (DEV_FD(dev)->block_size == 0 || \
- ((offset) % DEV_FD(dev)->block_size == 0 && \
- (count) % DEV_FD(dev)->block_size == 0))
-#define RAW_IO_ALIGN(dev, offset) \
- ((offset) / DEV_FD(dev)->block_size * DEV_FD(dev)->block_size)
-#define RAW_IO_MAX_SIZE (128 * 1024 * 1024)
-
-/* Define to nothing if not present on this system. */
-#ifndef O_EXCL
-# define O_EXCL 0
-#endif
-
-/**
- * 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)->fd, &sb) < 0) {
- ntfs_log_perror("Failed to stat '%s'", dev->d_name);
- return -1;
- }
-
- if (S_ISREG(sb.st_mode)) {
- DEV_FD(dev)->media_size = sb.st_size;
- ntfs_log_trace("%s: regular file (media_size %lld)\n",
- dev->d_name, DEV_FD(dev)->media_size);
- return 0;
- }
-
- if (ioctl(DEV_FD(dev)->fd, DIOCGSECTORSIZE, &bs) < 0) {
- ntfs_log_perror("Failed to ioctl(DIOCGSECTORSIZE) '%s'",
- dev->d_name);
- return -1;
- }
- DEV_FD(dev)->block_size = bs;
- ntfs_log_trace("%s: block size %d\n", dev->d_name, bs);
-
- if (ioctl(DEV_FD(dev)->fd, DIOCGMEDIASIZE, &ms) < 0) {
- ntfs_log_perror("Failed to ioctl(DIOCGMEDIASIZE) '%s'",
- dev->d_name);
- return -1;
- }
- DEV_FD(dev)->media_size = ms;
- ntfs_log_trace("%s: media size %lld\n", dev->d_name, ms);
- return 0;
-}
-
-/**
- * Aligned read
- */
-static ssize_t
-raw_io_pread(struct ntfs_device *dev, char *buf, size_t count, s64 offset)
-{
- return pread(DEV_FD(dev)->fd, buf, count, offset);
-}
-
-/**
- * Aligned write
- */
-static ssize_t
-raw_io_pwrite(struct ntfs_device *dev, const char *buf, size_t count, s64 offset)
-{
- return pwrite(DEV_FD(dev)->fd, buf, count, offset);
-}
-
-/**
- * ntfs_device_unix_raw_io_open - Open a device and lock it exclusively
- * @dev:
- * @flags:
- *
- * Description...
- *
- * Returns:
- */
-static int ntfs_device_unix_raw_io_open(struct ntfs_device *dev, int flags)
-{
-#if 0
- struct flock flk;
-#endif
- struct stat sbuf;
- int err;
-
- if (NDevOpen(dev)) {
- errno = EBUSY;
- return -1;
- }
- if (stat(dev->d_name, &sbuf)) {
- ntfs_log_perror("Failed to access '%s'", dev->d_name);
- return -1;
- }
- if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode))
- NDevSetBlock(dev);
-
- dev->d_private = malloc(sizeof(unix_raw_fd));
- if (!dev->d_private)
- return -1;
- DEV_FD(dev)->fd = -1;
- DEV_FD(dev)->pos = 0;
- DEV_FD(dev)->block_size = 0;
- DEV_FD(dev)->media_size = 0;
-
- /*
- * Open file for exclusive access if mounting r/w.
- * Fuseblk takes care about block devices.
- */
- if (!NDevBlock(dev) && (flags & O_RDWR) == O_RDWR)
- flags |= O_EXCL;
- DEV_FD(dev)->fd = open(dev->d_name, flags);
- if (DEV_FD(dev)->fd == -1) {
- err = errno;
- goto err_out;
- }
-
- if ((flags & O_RDWR) != O_RDWR)
- NDevSetReadOnly(dev);
-
-#if 0
- memset(&flk, 0, sizeof(flk));
- if (NDevReadOnly(dev))
- flk.l_type = F_RDLCK;
- else
- flk.l_type = F_WRLCK;
- flk.l_whence = SEEK_SET;
- flk.l_start = flk.l_len = 0LL;
- if (fcntl(DEV_FD(dev)->fd, F_SETLK, &flk)) {
- err = errno;
- ntfs_log_perror("Failed to %s lock '%s'", NDevReadOnly(dev) ?
- "read" : "write", dev->d_name);
- if (close(DEV_FD(dev)->fd))
- ntfs_log_perror("Failed to close '%s'", dev->d_name);
- goto err_out;
- }
-#endif
-
- if (raw_io_get_size(dev) < 0) {
- err = errno;
- close(DEV_FD(dev)->fd);
- goto err_out;
- }
-
- NDevSetOpen(dev);
- return 0;
-err_out:
- free(dev->d_private);
- dev->d_private = NULL;
- errno = err;
- return -1;
-}
-
-/**
- * ntfs_device_unix_raw_io_close - Close the device, releasing the lock
- * @dev:
- *
- * Description...
- *
- * Returns:
- */
-static int ntfs_device_unix_raw_io_close(struct ntfs_device *dev)
-{
-#if 0
- struct flock flk;
-#endif
-
- if (!NDevOpen(dev)) {
- errno = EBADF;
- return -1;
- }
- if (NDevDirty(dev))
- fsync(DEV_FD(dev)->fd);
-
-#if 0
- /* Release exclusive (mandatory) lock on the whole device. */
- 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)->fd, F_SETLK, &flk))
- ntfs_log_perror("ntfs_device_unix_raw_io_close: Warning: Could not "
- "unlock %s", dev->d_name);
-#endif
-
- /* Close the file descriptor and clear our open flag. */
- if (close(DEV_FD(dev)->fd))
- return -1;
- NDevClearOpen(dev);
- free(dev->d_private);
- dev->d_private = NULL;
- return 0;
-}
-
-/**
- * ntfs_device_unix_raw_io_seek - Seek to a place on the device
- * @dev:
- * @offset:
- * @whence:
- *
- * Description...
- *
- * Returns:
- */
-static s64 ntfs_device_unix_raw_io_seek(struct ntfs_device *dev, s64 offset,
- int whence)
-{
- 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_FD(dev)->pos + offset;
- break;
-
- case SEEK_END:
- abs_pos = DEV_FD(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_FD(dev)->media_size) {
- ntfs_log_trace("Seeking outsize seekable area.\n");
- errno = EINVAL;
- return -1;
- }
- DEV_FD(dev)->pos = abs_pos;
- return abs_pos;
-}
-
-/**
- * ntfs_device_unix_raw_io_read - Read from the device, from the current location
- * @dev:
- * @buf:
- * @count:
- *
- * Description...
- *
- * Returns:
- */
-static s64 ntfs_device_unix_raw_io_read(struct ntfs_device *dev, void *buf,
- s64 count)
-{
- s64 start, start_aligned;
- s64 end, end_aligned;
- size_t count_aligned;
- char *buf_aligned;
- ssize_t nr;
-
- /* short-circuit for regular files */
- start = DEV_FD(dev)->pos;
- if (count > RAW_IO_MAX_SIZE)
- count = RAW_IO_MAX_SIZE;
- if (RAW_IO_ALIGNED(dev, start, count)) {
- nr = raw_io_pread(dev, buf, count, start);
- if (nr <= 0)
- return nr;
-
- DEV_FD(dev)->pos += nr;
- return nr;
- }
-
- /*
- * +- 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_FD(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 = malloc(count_aligned);
- if (buf_aligned == NULL) {
- ntfs_log_trace("malloc(%d) failed\n", count_aligned);
- return -1;
- }
-
- /* read aligned data */
- nr = raw_io_pread(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;
- DEV_FD(dev)->pos += nr;
- return nr;
-}
-
-/**
- * ntfs_device_unix_raw_io_write - Write to the device, at the current location
- * @dev:
- * @buf:
- * @count:
- *
- * Description...
- *
- * Returns:
- */
-static s64 ntfs_device_unix_raw_io_write(struct ntfs_device *dev, const void *buf,
- s64 count)
-{
- 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 = DEV_FD(dev)->pos;
- if (count > RAW_IO_MAX_SIZE)
- count = RAW_IO_MAX_SIZE;
- if (RAW_IO_ALIGNED(dev, start, count)) {
- nw = raw_io_pwrite(dev, buf, count, start);
- if (nw <= 0)
- return nw;
-
- DEV_FD(dev)->pos += nw;
- return nw;
- }
-
- /*
- * +- 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_FD(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 = malloc(count_aligned);
- if (buf_aligned == NULL) {
- ntfs_log_trace("malloc(%d) failed\n", count_aligned);
- return -1;
- }
-
- /* read aligned lead-in */
- if (raw_io_pread(dev, buf_aligned, DEV_FD(dev)->block_size, start_aligned) != DEV_FD(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_FD(dev)->block_size) {
- if (raw_io_pread(dev, buf_aligned + count_aligned - DEV_FD(dev)->block_size, DEV_FD(dev)->block_size, end_aligned - DEV_FD(dev)->block_size) != DEV_FD(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 = raw_io_pwrite(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;
- DEV_FD(dev)->pos += nw;
- return nw;
-}
-
-/**
- * ntfs_device_unix_raw_io_pread - Perform a positioned read from the device
- * @dev:
- * @buf:
- * @count:
- * @offset:
- *
- * Description...
- *
- * Returns:
- */
-static s64 ntfs_device_unix_raw_io_pread(struct ntfs_device *dev, void *buf,
- s64 count, s64 offset)
-{
- return ntfs_pread(dev, offset, count, buf);
-}
-
-/**
- * ntfs_device_unix_raw_io_pwrite - Perform a positioned write to the device
- * @dev:
- * @buf:
- * @count:
- * @offset:
- *
- * Description...
- *
- * Returns:
- */
-static s64 ntfs_device_unix_raw_io_pwrite(struct ntfs_device *dev, const void *buf,
- s64 count, s64 offset)
-{
- if (NDevReadOnly(dev)) {
- errno = EROFS;
- return -1;
- }
- NDevSetDirty(dev);
-
- return ntfs_pwrite(dev, offset, count, buf);
-}
-
-/**
- * ntfs_device_unix_raw_io_sync - Flush any buffered changes to the device
- * @dev:
- *
- * Description...
- *
- * Returns:
- */
-static int ntfs_device_unix_raw_io_sync(struct ntfs_device *dev)
-{
- if (!NDevReadOnly(dev)) {
- int res = fsync(DEV_FD(dev)->fd);
- if (!res)
- NDevClearDirty(dev);
- return res;
- }
- return 0;
-}
-
-/**
- * ntfs_device_unix_raw_io_stat - Get information about the device
- * @dev:
- * @buf:
- *
- * Description...
- *
- * Returns:
- */
-static int ntfs_device_unix_raw_io_stat(struct ntfs_device *dev, struct stat *buf)
-{
- return fstat(DEV_FD(dev)->fd, buf);
-}
-
-/**
- * ntfs_device_unix_raw_io_ioctl - Perform an ioctl on the device
- * @dev:
- * @request:
- * @argp:
- *
- * Description...
- *
- * Returns:
- */
-static int ntfs_device_unix_raw_io_ioctl(struct ntfs_device *dev, int request,
- void *argp)
-{
- return ioctl(DEV_FD(dev)->fd, request, argp);
-}
-
-/**
- * Device operations for working with unix style devices and files.
- */
-struct ntfs_device_operations ntfs_device_unix_io_ops = {
- .open = ntfs_device_unix_raw_io_open,
- .close = ntfs_device_unix_raw_io_close,
- .seek = ntfs_device_unix_raw_io_seek,
- .read = ntfs_device_unix_raw_io_read,
- .write = ntfs_device_unix_raw_io_write,
- .pread = ntfs_device_unix_raw_io_pread,
- .pwrite = ntfs_device_unix_raw_io_pwrite,
- .sync = ntfs_device_unix_raw_io_sync,
- .stat = ntfs_device_unix_raw_io_stat,
- .ioctl = ntfs_device_unix_raw_io_ioctl,
-};