Did I say _attached patch_ ?!

Csaba
diff -r db37e331f7ed configure.ac
--- a/configure.ac      Mon Jan 01 20:24:11 2007 +0000
+++ b/configure.ac      Wed Jan 03 00:31:00 2007 +0100
@@ -80,17 +80,11 @@ AC_SYS_LARGEFILE
 AC_SYS_LARGEFILE
 
 case "$target_os" in
-linux*)
+linux*|freebsd*)
        PKG_CHECK_MODULES(FUSE_MODULE, fuse >= 2.6.0, [ 
compile_fuse_module=true ],
        [
                AC_MSG_ERROR([ntfs-3g requires FUSE >= 2.6.0. Please see 
http://fuse.sf.net/ or install __all__ FUSE packages (e.g. fuse, fuse-utils, 
libfuse, libfuse2, libfuse-dev) or remove already installed __older__ FUSE.])
        ]);;
-freebsd*)
-       AC_MSG_ERROR([Please see FreeBSD support at 
http://www.freshports.org/sysutils/fusefs-ntfs])
-       ;;
-*)
-               AC_MSG_ERROR([ntfs-3g can be built only under Linux.])
-       ;;
 esac
 
 # Static linking failed because FUSE 2.6.[01] forgot to include -lrt. 
diff -r db37e331f7ed libntfs-3g/Makefile.am
--- a/libntfs-3g/Makefile.am    Mon Jan 01 20:24:11 2007 +0000
+++ b/libntfs-3g/Makefile.am    Wed Jan 03 00:31:00 2007 +0100
@@ -53,7 +53,8 @@ libntfs_3g_la_SOURCES =       \
        security.c      \
        unistr.c        \
        version.c       \
-       volume.c
+       volume.c        \
+       ublio.c
 
 AM_CPPFLAGS = $(linux_ntfsincludedir) $(all_includes)
 
diff -r db37e331f7ed libntfs-3g/device.c
--- a/libntfs-3g/device.c       Mon Jan 01 20:24:11 2007 +0000
+++ b/libntfs-3g/device.c       Wed Jan 03 00:31:00 2007 +0100
@@ -62,6 +62,10 @@
 #endif
 #ifdef HAVE_LINUX_HDREG_H
 #include <linux/hdreg.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/disk.h>
 #endif
 
 #include "types.h"
@@ -531,6 +535,17 @@ s64 ntfs_device_size_get(struct ntfs_dev
                }
        }
 #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.
@@ -679,6 +694,23 @@ int ntfs_device_sector_size_get(struct n
                        return sect_size;
                }
        }
+#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
diff -r db37e331f7ed libntfs-3g/unix_io.c
--- a/libntfs-3g/unix_io.c      Mon Jan 01 20:24:11 2007 +0000
+++ b/libntfs-3g/unix_io.c      Wed Jan 03 00:31:00 2007 +0100
@@ -52,6 +52,22 @@
 #endif
 #ifdef HAVE_LINUX_FD_H
 #include <linux/fd.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/disk.h>
+#endif
+
+#define __FreeBSD_DIOC__ (defined(__FreeBSD__) && defined(DIOCGSECTORSIZE))
+#ifndef USE_UBLIO 
+  #if __FreeBSD_DIOC__
+    #define USE_UBLIO 1
+  #else
+    #define USE_UBLIO 0
+  #endif
+#endif
+#if USE_UBLIO
+#include <sys/uio.h>
 #endif
 
 #include "types.h"
@@ -61,7 +77,24 @@
 #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_BLOCKSIZE 512
+#define UBLIO_DEFAULT_ITEMS     12
+#define UBLIO_DEFAULT_GRACE     8
+#define UBLIO_DEFAULT_SYNC_IO   1
+#endif
+
+struct unix_filehandle {
+       int fd;
+#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
@@ -81,7 +114,14 @@ static int ntfs_device_unix_io_open(stru
 {
        struct flock flk;
        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,26 +131,55 @@ static int ntfs_device_unix_io_open(stru
                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)
-               return -1;
+       ufh = ntfs_malloc(sizeof(*ufh));
+       if (!ufh)
+               return -1;
+       dev->d_private = ufh;
        /*
         * 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;
        }
        
        if ((flags & O_RDWR) != O_RDWR)
                NDevSetReadOnly(dev);
+#if USE_UBLIO
+       ufh->ublio_fh = NULL;
+       if ((xenv = getenv("NTFS_USE_UBLIO")) &&
+           xenv[0] == '1' && xenv[1] == '\0')
+               use_ublio = 1;
+       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
        
        memset(&flk, 0, sizeof(flk));
        if (NDevReadOnly(dev))
@@ -119,7 +188,30 @@ static int ntfs_device_unix_io_open(stru
                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)) {
+#if __FreeBSD_DIOC__
+       {
+               size_t sectsize;
+
+               errno = 0;
+               ioctl(ufh->fd, DIOCGSECTORSIZE, &sectsize);
+               if (errno == 0) {
+#if USE_UBLIO
+                       use_ublio = 1;
+                       up.up_blocksize = sectsize;
+#endif
+                       NDevSetBlock(dev);
+               }
+       }
+#else
+       if (S_ISBLK(sbuf.st_mode))
+               NDevSetBlock(dev);
+#endif /* __FreeBSD_DIOC__ */
+       if (
+#if __FreeBSD_DIOC__
+           !NDevBlock(dev) &&
+#endif
+           fcntl(DEV_FD(dev), F_SETLK, &flk)
+          ) {
                err = errno;
                ntfs_log_perror("Failed to %s lock '%s'", NDevReadOnly(dev) ? 
                                "read" : "write", dev->d_name);
@@ -128,6 +220,15 @@ static int ntfs_device_unix_io_open(stru
                goto err_out;
        }
        
+#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,6 +248,7 @@ err_out:
  */
 static int ntfs_device_unix_io_close(struct ntfs_device *dev)
 {
+       /* XXX no error if fysnc, fcntl (ublio_close) fails? */
        struct flock flk;
 
        if (!NDevOpen(dev)) {
@@ -160,9 +262,17 @@ static int ntfs_device_unix_io_close(str
        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 (
+#if __FreeBSD_DIOC__
+           ! NDevBlock(dev) &&
+#endif
+           fcntl(DEV_FD(dev), F_SETLK, &flk))
                ntfs_log_perror("ntfs_device_unix_io_close: Warning: Could not "
                                "unlock %s", dev->d_name);
+#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;
@@ -201,6 +311,27 @@ static s64 ntfs_device_unix_io_read(stru
 static s64 ntfs_device_unix_io_read(struct ntfs_device *dev, void *buf,
                s64 count)
 {
+#if 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);
 }
 
@@ -222,6 +353,27 @@ static s64 ntfs_device_unix_io_write(str
                return -1;
        }
        NDevSetDirty(dev);
+#if 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);
 }
 
@@ -239,6 +391,12 @@ static s64 ntfs_device_unix_io_pread(str
 static s64 ntfs_device_unix_io_pread(struct ntfs_device *dev, void *buf,
                s64 count, s64 offset)
 {
+#if 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);
 }
 
@@ -261,6 +419,12 @@ static s64 ntfs_device_unix_io_pwrite(st
                return -1;
        }
        NDevSetDirty(dev);
+#if 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);
 }
 
@@ -275,7 +439,16 @@ static int ntfs_device_unix_io_sync(stru
 static int ntfs_device_unix_io_sync(struct ntfs_device *dev)
 {
        if (!NDevReadOnly(dev)) {
-               int res = fsync(DEV_FD(dev));
+               int res;
+
+#if USE_UBLIO
+               if (DEV_HANDLE(dev)->ublio_fh) {
+                       res = ublio_fsync(DEV_HANDLE(dev)->ublio_fh);
+                       if (res)
+                               return res;
+               }
+#endif
+               res = fsync(DEV_FD(dev));
                if (!res)
                        NDevClearDirty(dev);
                return res;
diff -r db37e331f7ed src/ntfs-3g.c
--- a/src/ntfs-3g.c     Mon Jan 01 20:24:11 2007 +0000
+++ b/src/ntfs-3g.c     Wed Jan 03 00:31:00 2007 +0100
@@ -138,6 +138,7 @@ static const char *locale_msg =
 "         be correct or visible. Please see the potential solution at\n"
 "         http://www.ntfs-3g.org/support.html#locale\n";;
 
+#ifdef linux
 static const char *fuse26_kmod_needed_msg =
 "ERROR: The FUSE kernel module 2.6.x is not available. Either remove the old\n"
 "       FUSE kernel module (use the command 'rmmod fuse') if you have the 
new\n"
@@ -146,6 +147,7 @@ static const char *fuse26_kmod_needed_ms
 "\n"
 "                  http://www.ntfs-3g.org/support.html#fuse26\n";
 "\n";
+#endif
 
 static __inline__ void ntfs_fuse_mark_free_space_outdated(void)
 {
@@ -1206,6 +1208,7 @@ static int ntfs_fuse_utime(const char *p
        return 0;
 }
 
+#ifdef linux
 static int ntfs_fuse_bmap(const char *path, size_t blocksize, uint64_t *idx)
 {
        ntfs_inode *ni;
@@ -1251,6 +1254,7 @@ close_inode:
                ntfs_log_perror("bmap: failed to close inode");
        return ret;
 }
+#endif
 
 #ifdef HAVE_SETXATTR
 
@@ -1576,7 +1580,11 @@ static struct fuse_operations ntfs_fuse_
        .mkdir          = ntfs_fuse_mkdir,
        .rmdir          = ntfs_fuse_rmdir,
        .utime          = ntfs_fuse_utime,
+#ifdef linux
        .bmap           = ntfs_fuse_bmap,
+#else
+       .bmap           = NULL,
+#endif
        .destroy        = ntfs_fuse_destroy2,
 #ifdef HAVE_SETXATTR
        .getxattr       = ntfs_fuse_getxattr,
@@ -1955,7 +1963,12 @@ static void load_fuse_module(int force)
 {
        struct stat st;
        int exist;
+#ifdef linux
        const char *load_fuse_cmd = "/sbin/modprobe fuse";
+#endif
+#ifdef __FreeBSD__
+       const char *load_fuse_cmd = "/sbin/kldload fuse";
+#endif
        
        exist = !stat("/dev/fuse", &st);
        
@@ -1967,15 +1980,22 @@ static void load_fuse_module(int force)
                        ntfs_log_perror("Failed to stat /dev/fuse");
                        return;
                }
-               
+#ifdef linux           
                if (mknod("/dev/fuse", S_IFCHR | 0666, makedev(10, 229))) {
                        ntfs_log_perror("Failed to create /dev/fuse");
                        return;
                }
-       }
-       
+#endif
+       }
+
+#ifdef linux           
        if (stat("/sbin/modprobe", &st) == -1)
                load_fuse_cmd = "modprobe fuse";
+#endif
+#ifdef __FreeBSD__
+       if (stat("/sbin/kldload", &st) == -1)
+               load_fuse_cmd = "kldload fuse";
+#endif
        
        if (getuid() == 0)
                system(load_fuse_cmd);
@@ -2001,7 +2021,8 @@ free_args:
        return fc;
                
 }
-               
+
+#ifdef linux
 static void set_fuseblk_options(char *parsed_options)
 {
        char option[32];
@@ -2043,6 +2064,7 @@ static int has_fuseblk(void)
        fclose(f);
        return 0;
 }
+#endif
 
 int main(int argc, char *argv[])
 {
@@ -2074,8 +2096,9 @@ int main(int argc, char *argv[])
                return 4;
        }
 
+#ifdef linux
        set_fuseblk_options(parsed_options);
-       
+#endif
        /* Libfuse can't always find fusermount, so let's help it. */
        if (setenv("PATH", ":/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin", 0))
                ntfs_log_perror("WARNING: Failed to set $PATH\n");
@@ -2090,9 +2113,10 @@ int main(int argc, char *argv[])
                        fc = try_fuse_mount(parsed_options);
                }
                if (!fc) {
+#ifdef linux
                        if (NDevBlock(ctx->vol->dev) && !has_fuseblk())
                                ntfs_log_error(fuse26_kmod_needed_msg);
-                       
+#endif
                        free(parsed_options);
                        ntfs_fuse_destroy();
                        return 5;
diff -r 9d74561f5f7c libntfs-3g/device_io.c
--- a/libntfs-3g/device_io.c    Sun Dec 24 22:49:35 2006 +0100
+++ b/libntfs-3g/device_io.c    Wed Jan 03 00:34:57 2007 +0100
@@ -23,16 +23,24 @@
 
 #ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
 
-#ifndef __CYGWIN32__
-
-/* Not on Cygwin; use standard Unix style low level device operations. */
-#include "unix_io.c"
-
-#else /* __CYGWIN32__ */
+#if defined(__CYGWIN32__)
 
 /* On Cygwin; use Win32 low level device operations. */
 #include "win32_io.c"
 
-#endif /* __CYGWIN32__ */
+#elif defined(__FreeBSD__) || 1
+
+/* On FreeBSD; need to use sector aligned i/o. */
+#include "freebsd_io.c"
+
+#else
+
+/*
+ * Not on Cygwin or FreeBSD; use standard Unix style low level device
+ * operations.
+ */
+#include "unix_io.c"
+
+#endif
 
 #endif /* NO_NTFS_DEVICE_DEFAULT_IO_OPS */
--- ../ntfsprogs-061227/libntfs/freebsd_io.c    2006-12-28 12:20:49.000000000 
+0100
+++ libntfs-3g/freebsd_io.c     2006-12-28 13:44:41.000000000 +0100
@@ -58,7 +58,9 @@
 #ifdef HAVE_LINUX_FD_H
 #include <linux/fd.h>
 #endif
+#ifdef __FreeBSD__
 #include <sys/disk.h>
+#endif
 
 #include "types.h"
 #include "mst.h"
@@ -92,8 +94,10 @@ typedef struct {
  */
 static int freebsd_get_size(struct ntfs_device *dev)
 {
+#ifdef __FreeBSD__
        off_t ms;
        int bs;
+#endif
        struct stat sb;
 
        if (fstat(DEV_FD(dev)->fd, &sb) < 0) {
@@ -104,8 +108,11 @@ static int freebsd_get_size(struct ntfs_
                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);
+               if (getenv("FORCE_ALIGNED_IO"))
+                       DEV_FD(dev)->block_size = 512;
                return 0;
        }
+#ifdef __FreeBSD__
        if (ioctl(DEV_FD(dev)->fd, DIOCGSECTORSIZE, &bs) < 0) {
                ntfs_log_perror("Failed to ioctl(DIOCGSECTORSIZE) '%s'",
                    dev->d_name);
@@ -119,6 +126,7 @@ static int freebsd_get_size(struct ntfs_
                return -1;
        }
        DEV_FD(dev)->media_size = ms;
+#endif
        ntfs_log_trace("%s: media size %lld\n", dev->d_name, ms);
        return 0;
 }
@@ -305,26 +313,27 @@ static s64 ntfs_device_freebsd_io_seek(s
 }
 
 /**
- * ntfs_device_freebsd_io_read - Read from the device, from the current 
location
+ * ntfs_device_freebsd_io_pread - Read from the device, from a given location
  * @dev:
  * @buf:
  * @count:
+ * @start:
  *
  * Description...
  *
  * Returns:
  */
-static s64 ntfs_device_freebsd_io_read(struct ntfs_device *dev, void *buf,
-               s64 count)
+static s64 ntfs_device_freebsd_io_pread(struct ntfs_device *dev, void *buf,
+               s64 count, s64 start)
 {
-       s64 start, start_aligned;
+       s64 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)) {
@@ -332,7 +341,6 @@ static s64 ntfs_device_freebsd_io_read(s
                if (nr <= 0)
                        return nr;
 
-               DEV_FD(dev)->pos += nr;
                return nr;
        }
 
@@ -380,24 +388,24 @@ static s64 ntfs_device_freebsd_io_read(s
        nr -= start - start_aligned;
        if (nr > count)
                nr = count;
-       DEV_FD(dev)->pos += nr;
        return nr;
 }
 
 /**
- * ntfs_device_freebsd_io_write - Write to the device, at the current location
+ * ntfs_device_freebsd_io_pwrite - Write to the device, at a given location
  * @dev:
  * @buf:
  * @count:
+ * @start:
  *
  * Description...
  *
  * Returns:
  */
-static s64 ntfs_device_freebsd_io_write(struct ntfs_device *dev, const void 
*buf,
-               s64 count)
+static s64 ntfs_device_freebsd_io_pwrite(struct ntfs_device *dev, const void 
*buf,
+                                        s64 count, s64 start)
 {
-       s64 start, start_aligned;
+       s64 start_aligned;
        s64 end, end_aligned;
        size_t count_aligned;
        char *buf_aligned;
@@ -410,7 +418,6 @@ static s64 ntfs_device_freebsd_io_write(
        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)) {
@@ -418,7 +425,6 @@ static s64 ntfs_device_freebsd_io_write(
                if (nw <= 0)
                        return nw;
 
-               DEV_FD(dev)->pos += nw;
                return nw;
        }
 
@@ -478,7 +484,52 @@ static s64 ntfs_device_freebsd_io_write(
        nw -= start - start_aligned;
        if (nw > count)
                nw = count;
-       DEV_FD(dev)->pos += nw;
+       return nw;
+}
+
+/**
+ * ntfs_device_freebsd_io_read - Read from the device, from the current 
location
+ * @dev:
+ * @buf:
+ * @count:
+ *
+ * Description...
+ *
+ * Returns:
+ */
+static s64 ntfs_device_freebsd_io_read(struct ntfs_device *dev, void *buf,
+               s64 count)
+{
+       ssize_t nr;
+
+       nr = ntfs_device_freebsd_io_pread(dev, buf, count, DEV_FD(dev)->pos);
+
+       if (nr > 0)
+               DEV_FD(dev)->pos += nr;
+
+       return nr;
+}
+       
+/**
+ * ntfs_device_freebsd_io_write - Write to the device, at the current location
+ * @dev:
+ * @buf:
+ * @count:
+ *
+ * Description...
+ *
+ * Returns:
+ */
+static s64 ntfs_device_freebsd_io_write(struct ntfs_device *dev, const void 
*buf,
+               s64 count)
+{
+       ssize_t nw;
+
+       nw = ntfs_device_freebsd_io_pwrite(dev, buf, count, DEV_FD(dev)->pos);
+
+       if (nw > 0)
+               DEV_FD(dev)->pos += nw;
+
        return nw;
 }
 
@@ -540,6 +591,8 @@ struct ntfs_device_operations ntfs_devic
        .seek           = ntfs_device_freebsd_io_seek,
        .read           = ntfs_device_freebsd_io_read,
        .write          = ntfs_device_freebsd_io_write,
+       .pread          = ntfs_device_freebsd_io_pread,
+       .pwrite         = ntfs_device_freebsd_io_pwrite,
        .sync           = ntfs_device_freebsd_io_sync,
        .stat           = ntfs_device_freebsd_io_stat,
        .ioctl          = ntfs_device_freebsd_io_ioctl,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
ntfs-3g-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ntfs-3g-devel

Reply via email to