diff options
Diffstat (limited to 'filesystems/ntfs')
-rw-r--r-- | filesystems/ntfs/Makefile | 61 | ||||
-rw-r--r-- | filesystems/ntfs/distinfo | 3 | ||||
-rw-r--r-- | filesystems/ntfs/files/README.FreeBSD | 126 | ||||
-rw-r--r-- | filesystems/ntfs/files/extra-patch-ublio | 27 | ||||
-rw-r--r-- | filesystems/ntfs/files/patch-configure | 30 | ||||
-rw-r--r-- | filesystems/ntfs/files/patch-libntfs-3g__unix_io.c | 623 | ||||
-rw-r--r-- | filesystems/ntfs/files/patch-ntfsprogs_mkntfs.c | 18 | ||||
-rw-r--r-- | filesystems/ntfs/files/pkg-message.in | 13 | ||||
-rw-r--r-- | filesystems/ntfs/pkg-descr | 4 | ||||
-rw-r--r-- | filesystems/ntfs/pkg-plist | 90 |
10 files changed, 995 insertions, 0 deletions
diff --git a/filesystems/ntfs/Makefile b/filesystems/ntfs/Makefile new file mode 100644 index 000000000000..2ff33fa98b38 --- /dev/null +++ b/filesystems/ntfs/Makefile @@ -0,0 +1,61 @@ +PORTNAME= ntfs +PORTVERSION= 2022.10.3 +PORTREVISION= 1 +CATEGORIES= filesystems +MASTER_SITES= https://download.tuxera.com/opensource/ +PKGNAMEPREFIX= fusefs- +DISTNAME= ${PORTNAME}-3g_ntfsprogs-${PORTVERSION} + +MAINTAINER= freebsd@dussan.org +COMMENT= Mount NTFS partitions (read/write) and disk images +WWW= https://github.com/tuxera/ntfs-3g + +LICENSE= GPLv2+ +LICENSE_FILE= ${WRKSRC}/COPYING + +LIB_DEPENDS= libuuid.so:misc/e2fsprogs-libuuid + +USES= fuse pkgconfig iconv libtool localbase:ldflags tar:tgz +USE_LDCONFIG= yes +GNU_CONFIGURE= yes +GNU_CONFIGURE_MANPREFIX=${PREFIX}/share +CONFIGURE_ARGS= --exec-prefix=${PREFIX} --disable-mount-helper \ + --disable-mtab --with-fuse=external --disable-ldconfig +INSTALL_TARGET= install-strip + +OPTIONS_DEFINE= CRYPTO DOCS EXTRAS LOCK UBLIO +OPTIONS_DEFAULT=EXTRAS LOCK UBLIO +OPTIONS_SUB= yes + +CRYPTO_DESC= Enable crypto-related code and utilities +CRYPTO_LIB_DEPENDS= libgcrypt.so:security/libgcrypt \ + libgnutls.so:security/gnutls \ + libgpg-error.so:security/libgpg-error +CRYPTO_CONFIGURE_ON= --enable-crypto + +EXTRAS_DESC= Build and install extra NTFS utilities +EXTRAS_CONFIGURE_ON= --enable-extras + +LOCK_DESC= Lock the device when mounting (avoids access) +LOCK_CFLAGS= -DUSE_LOCK + +UBLIO_DESC= Enable user space cache for improved speed +UBLIO_EXTRA_PATCHES= ${FILESDIR}/extra-patch-ublio +UBLIO_LIB_DEPENDS= libublio.so:devel/libublio +UBLIO_CFLAGS= -DUSE_UBLIO + +SUB_FILES= pkg-message +DOCSDIR= ${PREFIX}/share/doc/ntfs-3g + +post-patch: + @${REINPLACE_CMD} -e 's|ENODATA|ENOATTR|' \ + ${WRKSRC}/libntfs-3g/object_id.c \ + ${WRKSRC}/libntfs-3g/reparse.c \ + ${WRKSRC}/libntfs-3g/security.c + @${REINPLACE_CMD} -e '/$$(MAKE).*install-exec-hook/d' \ + ${WRKSRC}/libntfs-3g/Makefile.in + +post-install-DOCS-on: + ${INSTALL_DATA} ${FILESDIR}/README.FreeBSD ${STAGEDIR}${DOCSDIR}/ + +.include <bsd.port.mk> diff --git a/filesystems/ntfs/distinfo b/filesystems/ntfs/distinfo new file mode 100644 index 000000000000..51633f525273 --- /dev/null +++ b/filesystems/ntfs/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1666281899 +SHA256 (ntfs-3g_ntfsprogs-2022.10.3.tgz) = f20e36ee68074b845e3629e6bced4706ad053804cbaf062fbae60738f854170c +SIZE (ntfs-3g_ntfsprogs-2022.10.3.tgz) = 1324320 diff --git a/filesystems/ntfs/files/README.FreeBSD b/filesystems/ntfs/files/README.FreeBSD new file mode 100644 index 000000000000..ffaedb7707c3 --- /dev/null +++ b/filesystems/ntfs/files/README.FreeBSD @@ -0,0 +1,126 @@ +============================================================================== +NTFS-3G README for the FreeBSD port +============================================================================== + +1. Introduction +2. Port specific notes +3. Mounting at startup with /etc/fstab +4. Ublio configuration +5. Known issues + +============================================================================== +1. Introduction +============================================================================== + +The NTFS-3G project provides a read/write filesystem driver for NTFS. It uses +the FUSE library (an OS-independent library to create filesystem drivers) and +FreeBSD fusefs(5) kernel module (port of the kernel-dependent part of FUSE). +For more information see: + +NTFS-3G site: https://github.com/tuxera/ntfs-3g +FUSE site: https://github.com/libfuse/libfuse + +============================================================================== +2. Port specific notes +============================================================================== + +The port has a patch to align read/write operations to the media block size +(required on FreeBSD). + +The port has 2 options: LOCK (to prevent access to the device by external +programs than NTFS-3G once mounted, default on Linux), and UBLIO (use a user +space cache library, see devel/libublio, not required on Linux). + +The reason for using UBLIO is that FreeBSD removed support for block devices, +being them now character devices. The former ones had a cache, and NTFS-3G was +optimized for it (Linux still uses them). The same happens on Mac OS X (based +on FreeBSD 5). So using UBLIO both improves performance (~10 times faster), +and reduces disk load. + +============================================================================== +3. Mounting at startup with /etc/fstab +============================================================================== + +To mount at startup you need to have the following line in /boot/loader.conf: + + fusefs_load="YES" + +or have "fusefs" added to the "kld_list" in the /etc/rc.conf. + +Then create the following symlink: + +$ ln -s `which ntfs-3g` /usr/sbin/mount_ntfs-3g + +And add the appropriate line to /etc/fstab: the filesystem should be "ntfs-3g" +instead of "ntfs", and the additional "late" parameter is required. Example: + +/dev/ad4s1 /wxp ntfs-3g rw,late 0 0 + +============================================================================== +4. Ublio configuration +============================================================================== + +The UBLIO layer is configured through environment variables, which are read +when mounting the filesystem. The following are available: + +NTFS_USE_UBLIO - Enable the UBLIO cache. +UBLIO_BLOCKSIZE - Actual reads/writes will be multiples of this quantity. +UBLIO_ITEMS - Number of cache entries, each of UBLIO_BLOCKSIZE length. +UBLIO_GRACE - Number of times a cache entry will refuse being recycled. +UBLIO_SYNC_IO - If enabled, all writes will be immediately executed. + +To give an idea about tuning, here are the default values with some notes +(they are only based on some simple benchmarks, and may be wrong): + +NTFS_USE_UBLIO - 1. Disabling it drastically decreases performance. +UBLIO_BLOCKSIZE - 262144 (256KB). Larger improves reading/writing speed of + large files, and smaller makes filesystem operations + (creation, deletion, moving, find(1)) perform faster. + Try 2/4MB and 512/256KB for the different approaches. Note + that after that points performance decreases again. +UBLIO_ITEMS - 64. Higher increases speed of filesystem operations. Try 128. +UBLIO_GRACE - 32. Makes the cache items have more chances to be reused. +UBLIO_SYNC_IO - 0. If enabled, highly decreases writing speed, but the data + is immediately written to the disk. + +For example (improves performance over large files, but read below): + +# env UBLIO_BLOCKSIZE=2097152 ntfs-3g /dev/ad0s1 /mnt + +Alternatively these variables could be set in the shell startup file. For +example if you are using it in /etc/fstab add them to /etc/profile. If you use +it as a user, instead, editing the shell startup in HOME is enough. + +Note that higher values for UBLIO_BLOCKSIZE and UBLIO_ITEMS increase the +memory usage by their product in bytes. For example, if you set it to 1MB it +would consume 64MB. To decrease it to 16MB you could set UBLIO_BLOCKSIZE to +256KB (currently this is the default). Small values like 4096 can be used and +also perform fine. + +It is also possible to enforce block aligned I/O on regular files by setting +the FORCE_ALIGNED_IO variable (it will be set to 512 bytes), but this is only +useful for testing purposes and in practice has no use. + +============================================================================== +5. Known issues +============================================================================== + +- For mkntfs(8) -F must be used to allow non-block device to be processed. + +- Current implementation does not properly work with partitions of size which +is not a multiply of UBLIO_BLOCKSIZE (cannot read/write last cluster). For +instance, you may not be able to create ntfs filesystem because of this with + + Initializing device with zeroes: 99%Failed to complete writing to + /dev/ada0s1 after three retries. + +- When reading/writing the same file repeatedly while doing many simultaneous +operations on different files sometimes the former one fails: read(2) returns +-1 and sets errno to EAGAIN. This is because of a difference between the FUSE +kernel implementation in Linux and FreeBSD, and is being worked on. An example +scenario would be playing a song in XMMS, while building many ports, which +could cause XMMS skip the song. Another observed problem is the current +directory not being found, but entering again would work (Linux access is +path-based while FreeBSD is vnode-based, which may be reused). + +============================================================================== diff --git a/filesystems/ntfs/files/extra-patch-ublio b/filesystems/ntfs/files/extra-patch-ublio new file mode 100644 index 000000000000..36f1bb32acc9 --- /dev/null +++ b/filesystems/ntfs/files/extra-patch-ublio @@ -0,0 +1,27 @@ +--- ./libntfs-3g/Makefile.in.orig 2012-08-29 19:51:35.000000000 -0500 ++++ ./libntfs-3g/Makefile.in 2012-08-29 20:00:20.000000000 -0500 +@@ -251,6 +251,7 @@ + @INSTALL_LIBRARY_FALSE@noinst_LTLIBRARIES = libntfs-3g.la + libntfs_3g_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/include/ntfs-3g + libntfs_3g_la_LDFLAGS = -version-info $(LIBNTFS_3G_VERSION) -no-undefined ++libntfs_3g_la_LIBADD = -lublio + libntfs_3g_la_SOURCES = acls.c attrib.c attrlist.c bitmap.c bootsect.c \ + cache.c collate.c compat.c compress.c debug.c device.c dir.c \ + efs.c index.c inode.c lcnalloc.c logfile.c logging.c mft.c \ +--- src/ntfs-3g.c.orig 2011-04-10 20:04:41.000000000 +0200 ++++ src/ntfs-3g.c 2011-04-25 18:56:07.000000000 +0200 +@@ -3262,9 +3262,13 @@ + #else + .utime = ntfs_fuse_utime, + #endif ++#ifndef __FreeBSD__ ++ .bmap = ntfs_fuse_bmap, ++#else ++ .bmap = NULL, ++#endif + .fsync = ntfs_fuse_fsync, + .fsyncdir = ntfs_fuse_fsync, +- .bmap = ntfs_fuse_bmap, + .destroy = ntfs_fuse_destroy2, + #if !KERNELPERMS | (POSIXACLS & !KERNELACLS) + .access = ntfs_fuse_access, diff --git a/filesystems/ntfs/files/patch-configure b/filesystems/ntfs/files/patch-configure new file mode 100644 index 000000000000..cee7cc4a9090 --- /dev/null +++ b/filesystems/ntfs/files/patch-configure @@ -0,0 +1,30 @@ +--- configure.orig 2017-03-23 09:42:56 UTC ++++ configure +@@ -12871,7 +12871,7 @@ $as_echo_n "checking fuse compatibility... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking fuse compatibility" >&5 + $as_echo_n "checking fuse compatibility... " >&6; } + case "${target_os}" in +- linux*|solaris*) ++ freebsd*|linux*|solaris*) + + # Check whether --with-fuse was given. + if test "${with_fuse+set}" = set; then : +@@ -12885,9 +12885,6 @@ fi + darwin*|netbsd*|kfreebsd*-gnu) + with_fuse="external" + ;; +- freebsd*) +- as_fn_error $? "Please see FreeBSD support at http://www.freshports.org/sysutils/fusefs-ntfs" "$LINENO" 5 +- ;; + *) + as_fn_error $? "ntfs-3g can be built for Linux, FreeBSD, Mac OS X, NetBSD, and Solaris only." "$LINENO" 5 + ;; +@@ -15177,7 +15174,7 @@ fi + fi + + # Settings +-pkgconfigdir="\$(libdir)/pkgconfig" ++pkgconfigdir="\$(prefix)/libdata/pkgconfig" + ntfs3gincludedir="\$(includedir)/ntfs-3g" + # Executables should be installed to the root filesystem, otherwise + # automounting NTFS volumes can fail during boot if the driver binaries diff --git a/filesystems/ntfs/files/patch-libntfs-3g__unix_io.c b/filesystems/ntfs/files/patch-libntfs-3g__unix_io.c new file mode 100644 index 000000000000..b3e4c3dad80a --- /dev/null +++ b/filesystems/ntfs/files/patch-libntfs-3g__unix_io.c @@ -0,0 +1,623 @@ +--- libntfs-3g/unix_io.c.orig 2010-03-06 13:12:25.000000000 -0300 ++++ libntfs-3g/unix_io.c 2010-10-04 15:17:18.000000000 -0300 +@@ -54,6 +54,22 @@ + #include <linux/fd.h> + #endif + ++/* ++ * The following build definitions are available: ++ * USE_ALIGNED_IO - All I/O is done by blocks. ++ * USE_UBLIO - Use the ublio user space cache library. ++ * USE_LOCK - Lock the device/file when mounted. ++ */ ++ ++#ifdef __FreeBSD__ ++#include <sys/disk.h> ++#define USE_ALIGNED_IO 1 ++#endif ++ ++#if USE_UBLIO ++#include <sys/uio.h> ++#endif ++ + #include "types.h" + #include "mst.h" + #include "debug.h" +@@ -61,13 +77,90 @@ + #include "logging.h" + #include "misc.h" + +-#define DEV_FD(dev) (*(int *)dev->d_private) ++#if USE_UBLIO ++#define UBLIO_USE_API 1 ++#include "ublio.h" ++#define UBLIO_DEFAULT_ENABLE 1 ++#define UBLIO_DEFAULT_BLOCKSIZE 262144 ++#define UBLIO_DEFAULT_ITEMS 64 ++#define UBLIO_DEFAULT_GRACE 32 ++#define UBLIO_DEFAULT_SYNC_IO 0 ++#endif ++ ++#if USE_ALIGNED_IO ++#define RAW_IO_ALIGNED(dev, offset, count) \ ++ (DEV_HANDLE(dev)->block_size == 0 || \ ++ ((offset) % DEV_HANDLE(dev)->block_size == 0 && \ ++ (count) % DEV_HANDLE(dev)->block_size == 0)) ++#define RAW_IO_ALIGN(dev, offset) \ ++ ((offset) / DEV_HANDLE(dev)->block_size * DEV_HANDLE(dev)->block_size) ++#define RAW_IO_MAX_SIZE (128 * 1024 * 1024) ++#endif ++ ++struct unix_filehandle { ++ int fd; ++#if USE_ALIGNED_IO ++ s64 pos; ++ s32 block_size; ++ s64 media_size; ++#endif ++#if USE_UBLIO ++ ublio_filehandle_t ublio_fh; ++#endif ++}; ++ ++#define DEV_HANDLE(dev) ((struct unix_filehandle *)dev->d_private) ++#define DEV_FD(dev) (DEV_HANDLE(dev)->fd) + + /* Define to nothing if not present on this system. */ + #ifndef O_EXCL + # define O_EXCL 0 + #endif + ++#if USE_ALIGNED_IO ++/** ++ * Get block_size and media_size ++ */ ++static int ++raw_io_get_size(struct ntfs_device *dev) ++{ ++ int bs; ++ off_t ms; ++ struct stat sb; ++ ++ if (fstat(DEV_FD(dev), &sb) < 0) { ++ ntfs_log_perror("Failed to stat '%s'", dev->d_name); ++ return -1; ++ } ++ ++ if (S_ISREG(sb.st_mode)) { ++ DEV_HANDLE(dev)->media_size = sb.st_size; ++ ntfs_log_trace("%s: regular file (media_size %lld)\n", ++ dev->d_name, DEV_HANDLE(dev)->media_size); ++ if (getenv("FORCE_ALIGNED_IO")) ++ DEV_HANDLE(dev)->block_size = 512; ++ return 0; ++ } ++ ++ if (ioctl(DEV_FD(dev), DIOCGSECTORSIZE, &bs) < 0) { ++ ntfs_log_perror("Failed to ioctl(DIOCGSECTORSIZE) '%s'", ++ dev->d_name); ++ return -1; ++ } ++ DEV_HANDLE(dev)->block_size = bs; ++ ntfs_log_trace("%s: block size %d\n", dev->d_name, bs); ++ ++ if (ioctl(DEV_FD(dev), DIOCGMEDIASIZE, &ms) < 0) { ++ ntfs_log_perror("Failed to ioctl(DIOCGMEDIASIZE) '%s'", ++ dev->d_name); ++ return -1; ++ } ++ DEV_HANDLE(dev)->media_size = ms; ++ ntfs_log_trace("%s: media size %lld\n", dev->d_name, ms); ++ return 0; ++} ++#endif ++ + /** + * fsync replacement which makes every effort to try to get the data down to + * disk, using different means for different operating systems. Specifically, +@@ -113,9 +206,21 @@ + */ + static int ntfs_device_unix_io_open(struct ntfs_device *dev, int flags) + { ++#if USE_ALIGNED_IO ++ size_t sectsize; ++#endif ++#if USE_LOCK + struct flock flk; ++#endif + struct stat sbuf; +- int err; ++ struct unix_filehandle *ufh; ++ int err = 0; ++ int is_special = 0; ++#if USE_UBLIO ++ struct ublio_param up; ++ int use_ublio = 0; ++ char *xenv, *xgarbage; ++#endif + + if (NDevOpen(dev)) { + errno = EBUSY; +@@ -125,20 +230,28 @@ + ntfs_log_perror("Failed to access '%s'", dev->d_name); + return -1; + } +- if (S_ISBLK(sbuf.st_mode)) +- NDevSetBlock(dev); ++ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) ++ is_special = 1; + +- dev->d_private = ntfs_malloc(sizeof(int)); +- if (!dev->d_private) ++ ufh = ntfs_malloc(sizeof(*ufh)); ++ if (!ufh) + return -1; ++ dev->d_private = ufh; ++#if USE_ALIGNED_IO ++ ufh->fd = -1; ++ ufh->pos = 0; ++ ufh->block_size = 0; ++ ufh->media_size = 0; ++#endif ++ + /* + * Open file for exclusive access if mounting r/w. + * Fuseblk takes care about block devices. + */ +- if (!NDevBlock(dev) && (flags & O_RDWR) == O_RDWR) ++ if (!is_special && (flags & O_RDWR) == O_RDWR) + flags |= O_EXCL; +- *(int*)dev->d_private = open(dev->d_name, flags); +- if (*(int*)dev->d_private == -1) { ++ ufh->fd = open(dev->d_name, flags); ++ if (ufh->fd == -1) { + err = errno; + goto err_out; + } +@@ -146,6 +259,37 @@ + if ((flags & O_RDWR) != O_RDWR) + NDevSetReadOnly(dev); + ++#if USE_UBLIO ++ ufh->ublio_fh = NULL; ++ if ((xenv = getenv("NTFS_USE_UBLIO")) && ++ (xenv[0] == '0' || xenv[0] == '1') && xenv[1] == '\0') ++ use_ublio = (xenv[0] == '1'); ++ else ++ use_ublio = UBLIO_DEFAULT_ENABLE; ++ if ((xenv = getenv("UBLIO_BLOCKSIZE"))) ++ up.up_blocksize = strtoul(xenv, &xgarbage, 10); ++ if (!xenv || *xgarbage != '\0') ++ up.up_blocksize = UBLIO_DEFAULT_BLOCKSIZE; ++ if ((xenv = getenv("UBLIO_ITEMS"))) ++ up.up_items = strtoul(xenv, &xgarbage, 10); ++ if (!xenv || *xgarbage != '\0') ++ up.up_items = UBLIO_DEFAULT_ITEMS; ++ if ((xenv = getenv("UBLIO_GRACE"))) ++ up.up_grace = strtoul(xenv, &xgarbage, 10); ++ if (!xenv || *xgarbage != '\0') ++ up.up_grace = UBLIO_DEFAULT_GRACE; ++ if ((xenv = getenv("UBLIO_SYNC_IO")) && ++ (xenv[0] == '0' || xenv[0] == '1') && xenv[1] == '\0') ++ up.up_sync_io = (xenv[0] == '1'); ++ else ++ up.up_sync_io = UBLIO_DEFAULT_SYNC_IO; ++ up.up_priv = &ufh->fd; ++ up.up_pread = NULL; ++ up.up_preadv = NULL; ++ up.up_pwrite = NULL; ++ up.up_pwritev = NULL; ++#endif ++#if USE_LOCK + memset(&flk, 0, sizeof(flk)); + if (NDevReadOnly(dev)) + flk.l_type = F_RDLCK; +@@ -153,7 +297,21 @@ + flk.l_type = F_WRLCK; + flk.l_whence = SEEK_SET; + flk.l_start = flk.l_len = 0LL; +- if (fcntl(DEV_FD(dev), F_SETLK, &flk)) { ++#endif ++#if USE_ALIGNED_IO ++ if (raw_io_get_size(dev) < 0) { ++ err = errno; ++ close(DEV_FD(dev)); ++ goto err_out; ++ } ++ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) ++ NDevSetBlock(dev); ++#else ++ if (S_ISBLK(sbuf.st_mode)) ++ NDevSetBlock(dev); ++#endif /* USE_ALIGNED_IO */ ++#if USE_LOCK ++ if (!NDevBlock(dev) && fcntl(DEV_FD(dev), F_SETLK, &flk)) { + err = errno; + ntfs_log_perror("Failed to %s lock '%s'", NDevReadOnly(dev) ? + "read" : "write", dev->d_name); +@@ -161,7 +319,16 @@ + ntfs_log_perror("Failed to close '%s'", dev->d_name); + goto err_out; + } +- ++#endif ++#if USE_UBLIO ++ if (use_ublio) { ++ ufh->ublio_fh = ublio_open(&up); ++ if (!ufh->ublio_fh) { ++ close(DEV_FD(dev)); ++ goto err_out; ++ } ++ } ++#endif + NDevSetOpen(dev); + return 0; + err_out: +@@ -181,7 +348,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; +@@ -194,12 +364,18 @@ + return -1; + } + ++#if USE_LOCK + memset(&flk, 0, sizeof(flk)); + flk.l_type = F_UNLCK; + flk.l_whence = SEEK_SET; + flk.l_start = flk.l_len = 0LL; +- if (fcntl(DEV_FD(dev), F_SETLK, &flk)) ++ if (!NDevBlock(dev) && fcntl(DEV_FD(dev), F_SETLK, &flk)) + ntfs_log_perror("Could not unlock %s", dev->d_name); ++#endif ++#if USE_UBLIO ++ if (DEV_HANDLE(dev)->ublio_fh) ++ ublio_close(DEV_HANDLE(dev)->ublio_fh); ++#endif + if (close(DEV_FD(dev))) { + ntfs_log_perror("Failed to close device %s", dev->d_name); + return -1; +@@ -223,9 +399,234 @@ + static s64 ntfs_device_unix_io_seek(struct ntfs_device *dev, s64 offset, + int whence) + { ++#if USE_ALIGNED_IO ++ s64 abs_pos; ++ ++ ntfs_log_trace("seek offset = 0x%llx, whence = %d.\n", offset, whence); ++ switch (whence) { ++ case SEEK_SET: ++ abs_pos = offset; ++ break; ++ ++ case SEEK_CUR: ++ abs_pos = DEV_HANDLE(dev)->pos + offset; ++ break; ++ ++ case SEEK_END: ++ abs_pos = DEV_HANDLE(dev)->media_size + offset; ++ break; ++ ++ default: ++ ntfs_log_trace("Wrong mode %d.\n", whence); ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if (abs_pos < 0 || abs_pos > DEV_HANDLE(dev)->media_size) { ++ ntfs_log_trace("Seeking outsize seekable area.\n"); ++ errno = EINVAL; ++ return -1; ++ } ++ DEV_HANDLE(dev)->pos = abs_pos; ++ return abs_pos; ++#else + return lseek(DEV_FD(dev), offset, whence); ++#endif + } + ++#if USE_ALIGNED_IO ++ ++#if USE_UBLIO ++#define pread_wrap(fd, buf, count, off) \ ++ (DEV_HANDLE(fd)->ublio_fh ? \ ++ ublio_pread(DEV_HANDLE(fd)->ublio_fh, buf, count, off) : \ ++ pread(DEV_FD(fd), buf, count, off)) ++#define pwrite_wrap(fd, buf, count, off) \ ++ (DEV_HANDLE(fd)->ublio_fh ? \ ++ ublio_pwrite(DEV_HANDLE(fd)->ublio_fh, buf, count, off) : \ ++ pwrite(DEV_FD(fd), buf, count, off)) ++#else ++#define pread_wrap(fd, buf, count, off) \ ++ pread(DEV_FD(fd), buf, count, off) ++#define pwrite_wrap(fd, buf, count, off) \ ++ pwrite(DEV_FD(fd), buf, count, off) ++#endif ++ ++/** ++ * aligned_pread - Perform an aligned positioned read from the device ++ */ ++static s64 aligned_pread(struct ntfs_device *dev, void *buf, s64 count, s64 offset) ++{ ++ s64 start, start_aligned; ++ s64 end, end_aligned; ++ size_t count_aligned; ++ char *buf_aligned; ++ ssize_t nr; ++ ++ /* short-circuit for regular files */ ++ start = offset; ++ if (count > RAW_IO_MAX_SIZE) ++ count = RAW_IO_MAX_SIZE; ++ if (RAW_IO_ALIGNED(dev, start, count)) ++ return pread_wrap(dev, buf, count, start); ++ ++ /* ++ * +- start_aligned +- end_aligned ++ * | | ++ * | +- start +- end | ++ * v v v v ++ * |----------|----------|----------| ++ * ^ ^ ++ * +----- count ------+ ++ * ^ ^ ++ * +-------- count_aligned ---------+ ++ */ ++ start_aligned = RAW_IO_ALIGN(dev, start); ++ end = start + count; ++ end_aligned = RAW_IO_ALIGN(dev, end) + ++ (RAW_IO_ALIGNED(dev, end, 0) ? 0 : DEV_HANDLE(dev)->block_size); ++ count_aligned = end_aligned - start_aligned; ++ ntfs_log_trace( ++ "%s: count = 0x%llx/0x%x, start = 0x%llx/0x%llx, end = 0x%llx/0x%llx\n", ++ dev->d_name, count, count_aligned, ++ start, start_aligned, end, end_aligned); ++ ++ /* allocate buffer */ ++ buf_aligned = ntfs_malloc(count_aligned); ++ if (buf_aligned == NULL) { ++ ntfs_log_trace("ntfs_malloc(%d) failed\n", count_aligned); ++ return -1; ++ } ++ ++ /* read aligned data */ ++ nr = pread_wrap(dev, buf_aligned, count_aligned, start_aligned); ++ if (nr == 0) ++ return 0; ++ if (nr < 0 || nr < start - start_aligned) { ++ free(buf_aligned); ++ return -1; ++ } ++ ++ /* copy out */ ++ memcpy(buf, buf_aligned + (start - start_aligned), count); ++ free(buf_aligned); ++ ++ nr -= start - start_aligned; ++ if (nr > count) ++ nr = count; ++ return nr; ++} ++ ++/** ++ * aligned_pwrite - Perform an aligned positioned write from the device ++ */ ++static s64 aligned_pwrite(struct ntfs_device *dev, void *buf, s64 count, s64 offset) ++{ ++ s64 start, start_aligned; ++ s64 end, end_aligned; ++ size_t count_aligned; ++ char *buf_aligned; ++ ssize_t nw; ++ ++ if (NDevReadOnly(dev)) { ++ errno = EROFS; ++ return -1; ++ } ++ NDevSetDirty(dev); ++ ++ /* short-circuit for regular files */ ++ start = offset; ++ if (count > RAW_IO_MAX_SIZE) ++ count = RAW_IO_MAX_SIZE; ++ if (RAW_IO_ALIGNED(dev, start, count)) ++ return pwrite_wrap(dev, buf, count, start); ++ ++ /* ++ * +- start_aligned +- end_aligned ++ * | | ++ * | +- start +- end | ++ * v v v v ++ * |----------|----------|----------| ++ * ^ ^ ++ * +----- count ------+ ++ * ^ ^ ++ * +-------- count_aligned ---------+ ++ */ ++ start_aligned = RAW_IO_ALIGN(dev, start); ++ end = start + count; ++ end_aligned = RAW_IO_ALIGN(dev, end) + ++ (RAW_IO_ALIGNED(dev, end, 0) ? 0 : DEV_HANDLE(dev)->block_size); ++ count_aligned = end_aligned - start_aligned; ++ ntfs_log_trace( ++ "%s: count = 0x%llx/0x%x, start = 0x%llx/0x%llx, end = 0x%llx/0x%llx\n", ++ dev->d_name, count, count_aligned, ++ start, start_aligned, end, end_aligned); ++ ++ /* allocate buffer */ ++ buf_aligned = ntfs_malloc(count_aligned); ++ if (buf_aligned == NULL) { ++ ntfs_log_trace("ntfs_malloc(%d) failed\n", count_aligned); ++ return -1; ++ } ++ ++ /* read aligned lead-in */ ++ if (pread_wrap(dev, buf_aligned, DEV_HANDLE(dev)->block_size, start_aligned) != DEV_HANDLE(dev)->block_size) { ++ ntfs_log_trace("read lead-in failed\n"); ++ free(buf_aligned); ++ return -1; ++ } ++ ++ /* read aligned lead-out */ ++ if (end != end_aligned && count_aligned > DEV_HANDLE(dev)->block_size) { ++ if (pread_wrap(dev, buf_aligned + count_aligned - DEV_HANDLE(dev)->block_size, DEV_HANDLE(dev)->block_size, end_aligned - DEV_HANDLE(dev)->block_size) != DEV_HANDLE(dev)->block_size) { ++ ntfs_log_trace("read lead-out failed\n"); ++ free(buf_aligned); ++ return -1; ++ } ++ } ++ ++ /* copy data to write */ ++ memcpy(buf_aligned + (start - start_aligned), buf, count); ++ ++ /* write aligned data */ ++ nw = pwrite_wrap(dev, buf_aligned, count_aligned, start_aligned); ++ free(buf_aligned); ++ if (nw < 0 || nw < start - start_aligned) ++ return -1; ++ ++ nw -= start - start_aligned; ++ if (nw > count) ++ nw = count; ++ return nw; ++} ++ ++/** ++ * aligned_read - Perform an aligned read from the device ++ */ ++static s64 aligned_read(struct ntfs_device *dev, void *buf, s64 count) ++{ ++ s64 nr = aligned_pread(dev, buf, count, DEV_HANDLE(dev)->pos); ++ if (nr > 0) ++ DEV_HANDLE(dev)->pos += nr; ++ return nr; ++} ++ ++/** ++ * aligned_write - Perform an aligned read from the device ++ */ ++static s64 aligned_write(struct ntfs_device *dev, void *buf, s64 count) ++{ ++ s64 nw = aligned_pwrite(dev, buf, count, DEV_HANDLE(dev)->pos); ++ if (nw > 0) ++ DEV_HANDLE(dev)->pos += nw; ++ return nw; ++} ++ ++#undef ublio_pwrite ++#undef ublio_pread ++ ++#endif ++ + /** + * ntfs_device_unix_io_read - Read from the device, from the current location + * @dev: +@@ -239,6 +640,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); + } + +@@ -260,6 +684,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); + } + +@@ -277,6 +723,13 @@ + static s64 ntfs_device_unix_io_pread(struct ntfs_device *dev, void *buf, + s64 count, s64 offset) + { ++#if USE_ALIGNED_IO ++ return aligned_pread(dev, buf, count, offset); ++#elif USE_UBLIO ++ if (DEV_HANDLE(dev)->ublio_fh) ++ return ublio_pread(DEV_HANDLE(dev)->ublio_fh, buf, count, ++ offset); ++#endif + return pread(DEV_FD(dev), buf, count, offset); + } + +@@ -299,6 +752,13 @@ + return -1; + } + NDevSetDirty(dev); ++#if USE_ALIGNED_IO ++ return aligned_pwrite(dev, buf, count, offset); ++#elif USE_UBLIO ++ if (DEV_HANDLE(dev)->ublio_fh) ++ return ublio_pwrite(DEV_HANDLE(dev)->ublio_fh, (void *)buf, ++ count, offset); ++#endif + return pwrite(DEV_FD(dev), buf, count, offset); + } + +@@ -315,7 +775,14 @@ + int res = 0; + + if (!NDevReadOnly(dev)) { ++#if USE_UBLIO ++ if (DEV_HANDLE(dev)->ublio_fh) ++ res = ublio_fsync(DEV_HANDLE(dev)->ublio_fh); ++ if (!DEV_HANDLE(dev)->ublio_fh || !res) ++ res = ntfs_fsync(DEV_FD(dev)); ++#else + res = ntfs_fsync(DEV_FD(dev)); ++#endif + if (res) + ntfs_log_perror("Failed to sync device %s", dev->d_name); + else diff --git a/filesystems/ntfs/files/patch-ntfsprogs_mkntfs.c b/filesystems/ntfs/files/patch-ntfsprogs_mkntfs.c new file mode 100644 index 000000000000..4338563b5e04 --- /dev/null +++ b/filesystems/ntfs/files/patch-ntfsprogs_mkntfs.c @@ -0,0 +1,18 @@ +--- ntfsprogs/mkntfs.c.orig 2015-03-14 14:10:12 UTC ++++ ntfsprogs/mkntfs.c +@@ -3488,6 +3488,7 @@ static BOOL mkntfs_open_partition(ntfs_v + goto done; + } + ++#ifndef __FreeBSD__ + if (!S_ISBLK(sbuf.st_mode)) { + ntfs_log_error("%s is not a block device.\n", vol->dev->d_name); + if (!opts.force) { +@@ -3526,6 +3527,7 @@ static BOOL mkntfs_open_partition(ntfs_v + ntfs_log_warning("mkntfs forced anyway.\n"); + #endif + } ++#endif + /* Make sure the file system is not mounted. */ + if (ntfs_check_if_mounted(vol->dev->d_name, &mnt_flags)) { + ntfs_log_perror("Failed to determine whether %s is mounted", vol->dev->d_name); diff --git a/filesystems/ntfs/files/pkg-message.in b/filesystems/ntfs/files/pkg-message.in new file mode 100644 index 000000000000..dad797469e8e --- /dev/null +++ b/filesystems/ntfs/files/pkg-message.in @@ -0,0 +1,13 @@ +[ +{ type: install + message: <<EOM +NTFS-3G has been installed. It requires fusefs(5) support to operate, +so issue the ``kldload fusefs'' command or ``sysrc kld_list+=fusefs'' +to make it load automatically when the system starts. + +For further information, implementation details, and known issues see +the FreeBSD README (%%DOCSDIR%%/README.FreeBSD) in +addition to the official README (contains some Linux-specific parts). +EOM +} +] diff --git a/filesystems/ntfs/pkg-descr b/filesystems/ntfs/pkg-descr new file mode 100644 index 000000000000..539b307f498c --- /dev/null +++ b/filesystems/ntfs/pkg-descr @@ -0,0 +1,4 @@ +The ntfs-3g driver is an open-source, freely available read/write NTFS +driver which provides safe and fast handling of the Windows NTFS file +systems. Almost the full POSIX filesystem functionality is supported, +the major exceptions are changing file ownership and the access rights. diff --git a/filesystems/ntfs/pkg-plist b/filesystems/ntfs/pkg-plist new file mode 100644 index 000000000000..93dcc52a90fd --- /dev/null +++ b/filesystems/ntfs/pkg-plist @@ -0,0 +1,90 @@ +bin/lowntfs-3g +bin/ntfs-3g +bin/ntfs-3g.probe +bin/ntfscat +bin/ntfscluster +bin/ntfscmp +%%CRYPTO%%%%EXTRAS%%bin/ntfsdecrypt +bin/ntfsfix +bin/ntfsinfo +bin/ntfsls +%%EXTRAS%%bin/ntfsrecover +%%EXTRAS%%bin/ntfssecaudit +%%EXTRAS%%bin/ntfstruncate +%%EXTRAS%%bin/ntfsusermap +%%EXTRAS%%bin/ntfswipe +include/ntfs-3g/acls.h +include/ntfs-3g/attrib.h +include/ntfs-3g/attrlist.h +include/ntfs-3g/bitmap.h +include/ntfs-3g/bootsect.h +include/ntfs-3g/cache.h +include/ntfs-3g/collate.h +include/ntfs-3g/compat.h +include/ntfs-3g/compress.h +include/ntfs-3g/debug.h +include/ntfs-3g/device.h +include/ntfs-3g/device_io.h +include/ntfs-3g/dir.h +include/ntfs-3g/ea.h +include/ntfs-3g/efs.h +include/ntfs-3g/endians.h +include/ntfs-3g/index.h +include/ntfs-3g/inode.h +include/ntfs-3g/ioctl.h +include/ntfs-3g/layout.h +include/ntfs-3g/lcnalloc.h +include/ntfs-3g/logfile.h +include/ntfs-3g/logging.h +include/ntfs-3g/mft.h +include/ntfs-3g/misc.h +include/ntfs-3g/mst.h +include/ntfs-3g/ntfstime.h +include/ntfs-3g/object_id.h +include/ntfs-3g/param.h +include/ntfs-3g/plugin.h +include/ntfs-3g/realpath.h +include/ntfs-3g/reparse.h +include/ntfs-3g/runlist.h +include/ntfs-3g/security.h +include/ntfs-3g/support.h +include/ntfs-3g/types.h +include/ntfs-3g/unistr.h +include/ntfs-3g/volume.h +include/ntfs-3g/xattrs.h +lib/libntfs-3g.a +lib/libntfs-3g.so +lib/libntfs-3g.so.89 +lib/libntfs-3g.so.89.0.0 +libdata/pkgconfig/libntfs-3g.pc +share/man/man8/mkntfs.8.gz +share/man/man8/ntfs-3g.8.gz +share/man/man8/ntfs-3g.probe.8.gz +share/man/man8/ntfscat.8.gz +share/man/man8/ntfsclone.8.gz +share/man/man8/ntfscluster.8.gz +share/man/man8/ntfscmp.8.gz +share/man/man8/ntfscp.8.gz +share/man/man8/ntfsdecrypt.8.gz +share/man/man8/ntfsfallocate.8.gz +share/man/man8/ntfsfix.8.gz +share/man/man8/ntfsinfo.8.gz +share/man/man8/ntfslabel.8.gz +share/man/man8/ntfsls.8.gz +share/man/man8/ntfsprogs.8.gz +share/man/man8/ntfsrecover.8.gz +share/man/man8/ntfsresize.8.gz +share/man/man8/ntfssecaudit.8.gz +share/man/man8/ntfstruncate.8.gz +share/man/man8/ntfsundelete.8.gz +share/man/man8/ntfsusermap.8.gz +share/man/man8/ntfswipe.8.gz +sbin/mkntfs +sbin/ntfsclone +sbin/ntfscp +sbin/ntfslabel +sbin/ntfsresize +sbin/ntfsundelete +%%PORTDOCS%%%%DOCSDIR%%/README +%%PORTDOCS%%%%DOCSDIR%%/README.FreeBSD +@dir lib/ntfs-3g |