diff options
author | Alejandro Pulver <alepulver@FreeBSD.org> | 2007-10-30 03:22:04 +0000 |
---|---|---|
committer | Alejandro Pulver <alepulver@FreeBSD.org> | 2007-10-30 03:22:04 +0000 |
commit | cf9758e30f7959f1f1b7627500276d3eaf2990ae (patch) | |
tree | 82ca3b72ed42f5d8e9a9ad64ce4891d5142af653 /sysutils/ntfsprogs/files | |
parent | c548b8970f62d05b33e404db5046067675baf74d (diff) |
Notes
Diffstat (limited to 'sysutils/ntfsprogs/files')
-rw-r--r-- | sysutils/ntfsprogs/files/patch-libntfs-device.c | 56 | ||||
-rw-r--r-- | sysutils/ntfsprogs/files/patch-libntfs-device_io.c | 14 | ||||
-rw-r--r-- | sysutils/ntfsprogs/files/patch-libntfs-unix_io.c | 624 | ||||
-rw-r--r-- | sysutils/ntfsprogs/files/patch-ntfsprogs-Makefile.in | 19 | ||||
-rw-r--r-- | sysutils/ntfsprogs/files/pkg-message.in | 13 | ||||
-rw-r--r-- | sysutils/ntfsprogs/files/unix_io_raw.c | 593 |
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, §_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, -}; |