aboutsummaryrefslogtreecommitdiff
path: root/sysutils/fusefs-exfat
diff options
context:
space:
mode:
authorAlexander Logvinov <avl@FreeBSD.org>2012-01-31 05:42:27 +0000
committerAlexander Logvinov <avl@FreeBSD.org>2012-01-31 05:42:27 +0000
commit56d98a01a1b0f94709e1ae192579e1c562e0642e (patch)
tree5dec614bc4c5a1ae29acdd1932f9234eda0091cb /sysutils/fusefs-exfat
parentd394b3aa7c337444391245da678c267745bb6096 (diff)
downloadports-56d98a01a1b0f94709e1ae192579e1c562e0642e.tar.gz
ports-56d98a01a1b0f94709e1ae192579e1c562e0642e.zip
exfat-fuse is a free exFAT file system implementation with write support.
exFAT is a simple file system created by Microsoft. It is intended to replace FAT32 removing some of it's limitations. exFAT is a standard FS for SDXC memory cards. WWW: http://code.google.com/p/exfat/ PR: ports/164473 Submitted by: Alex Samorukov <samm at os2.kiev.ua>
Notes
Notes: svn path=/head/; revision=290151
Diffstat (limited to 'sysutils/fusefs-exfat')
-rw-r--r--sysutils/fusefs-exfat/Makefile38
-rw-r--r--sysutils/fusefs-exfat/distinfo2
-rw-r--r--sysutils/fusefs-exfat/files/patch-SConstruct22
-rw-r--r--sysutils/fusefs-exfat/files/patch-libexfat_io.c192
-rw-r--r--sysutils/fusefs-exfat/pkg-descr6
5 files changed, 260 insertions, 0 deletions
diff --git a/sysutils/fusefs-exfat/Makefile b/sysutils/fusefs-exfat/Makefile
new file mode 100644
index 000000000000..cf9da4f4c2f4
--- /dev/null
+++ b/sysutils/fusefs-exfat/Makefile
@@ -0,0 +1,38 @@
+# New ports collection makefile for: fusefs-exfat
+# Date created: 2012-01-25
+# Whom: Alex Samorukov <samm@os2.kiev.ua>
+#
+# $FreeBSD$
+#
+
+PORTNAME= exfat
+PORTVERSION= 0.9.6
+CATEGORIES= sysutils
+MASTER_SITES= GOOGLE_CODE
+PKGNAMEPREFIX= fusefs-
+DISTNAME= fuse-${PORTNAME}-${PORTVERSION}
+
+MAINTAINER= samm@os2.kiev.ua
+COMMENT= A full-featured exFAT FS implementation as a FUSE module
+
+LICENSE= GPLv3
+
+LIB_DEPENDS= fuse.2:${PORTSDIR}/sysutils/fusefs-libs
+RUN_DEPENDS= ${LOCALBASE}/modules/fuse.ko:${PORTSDIR}/sysutils/fusefs-kmod
+
+USE_ICONV= yes
+USE_SCONS= yes
+SCONS_ENV+= LIBPATH=${PREFIX}/lib
+SCONS_BUILDENV= ${SCONS_ENV} CXXFLAGS=" -I${LOCALBASE}/include " \
+ LDFLAGS=" -L${LOCALBASE}/lib "
+SCONS_ARGS+= prefix=${PREFIX} use_env=1
+
+MAN8= mount.exfat-fuse.8
+PLIST_FILES= bin/mount.exfat-fuse bin/mount.exfat
+
+do-install:
+ ${INSTALL_PROGRAM} ${WRKSRC}/fuse/mount.exfat-fuse ${PREFIX}/bin
+ ${LN} -s ${PREFIX}/bin/mount.exfat-fuse ${PREFIX}/bin/mount.exfat
+ ${INSTALL_MAN} ${WRKSRC}/fuse/${MAN8} ${MAN8PREFIX}/man/man8
+
+.include <bsd.port.mk>
diff --git a/sysutils/fusefs-exfat/distinfo b/sysutils/fusefs-exfat/distinfo
new file mode 100644
index 000000000000..ec65b8256360
--- /dev/null
+++ b/sysutils/fusefs-exfat/distinfo
@@ -0,0 +1,2 @@
+SHA256 (fuse-exfat-0.9.6.tar.gz) = c084e5149de279039266583077763b9c85c0e85ba7397dccccc07e2cc51b5c4c
+SIZE (fuse-exfat-0.9.6.tar.gz) = 36951
diff --git a/sysutils/fusefs-exfat/files/patch-SConstruct b/sysutils/fusefs-exfat/files/patch-SConstruct
new file mode 100644
index 000000000000..64eec4ed23ea
--- /dev/null
+++ b/sysutils/fusefs-exfat/files/patch-SConstruct
@@ -0,0 +1,22 @@
+--- SConstruct.orig 2012-01-25 09:15:01.332956305 +0000
++++ SConstruct 2012-01-25 09:15:48.373957139 +0000
+@@ -41,6 +41,19 @@
+ env.Append(CPPPATH = ['libexfat'])
+ env.Append(LINKFLAGS = '')
+
++# ---- check for environment variables
++if 'CXX' in os.environ:
++ env.Replace(CXX = os.environ['CXX'])
++ print(">> Using compiler " + os.environ['CXX'])
++
++if 'CXXFLAGS' in os.environ:
++ env.Append(CCFLAGS = os.environ['CXXFLAGS'])
++ print(">> Appending custom build flags : " + os.environ['CXXFLAGS'])
++
++if 'LDFLAGS' in os.environ:
++ env.Append(LINKFLAGS = os.environ['LDFLAGS'])
++ print(">> Appending custom link flags : " + os.environ['LDFLAGS'])
++
+ def make_symlink(dir, target, link_name):
+ workdir = os.getcwd()
+ os.chdir(dir)
diff --git a/sysutils/fusefs-exfat/files/patch-libexfat_io.c b/sysutils/fusefs-exfat/files/patch-libexfat_io.c
new file mode 100644
index 000000000000..b4e62ab9e796
--- /dev/null
+++ b/sysutils/fusefs-exfat/files/patch-libexfat_io.c
@@ -0,0 +1,192 @@
+--- libexfat/io.c 2012-01-25 13:07:21.467957180 +0000
++++ libexfat/io.c 2012-01-25 13:26:10.599952890 +0000
+@@ -23,6 +23,7 @@
+ #include <sys/types.h>
+ #include <sys/uio.h>
+ #include <sys/stat.h>
++#include <string.h>
+ #include <fcntl.h>
+ #define __USE_UNIX98 /* for pread() in Linux */
+ #include <unistd.h>
+@@ -49,26 +50,177 @@
+ exfat_error("failed to fstat `%s'", spec);
+ return -1;
+ }
+- if (!S_ISBLK(stbuf.st_mode) && !S_ISREG(stbuf.st_mode))
++ if (!S_ISCHR(stbuf.st_mode) && !S_ISREG(stbuf.st_mode) && !S_ISBLK(stbuf.st_mode))
+ {
+ close(fd);
+- exfat_error("`%s' is neither a block device, nor a regular file",
++ exfat_error("`%s' is neither a special device, nor a regular file",
+ spec);
+ return -1;
+ }
+ return fd;
+ }
+
++#define RAW_IO_MAX_SIZE (128 * 1024 * 1024)
++#define DEVBSIZE 512 // better get from the device, but 512 should work as well
++#define RAW_IO_ALIGNED(offset, count) \
++ (DEVBSIZE == 0 || \
++ ((offset) % DEVBSIZE == 0 && \
++ (count) % DEVBSIZE == 0))
++#define RAW_IO_ALIGN(offset) \
++ ((offset) / DEVBSIZE * DEVBSIZE)
++#define RAW_IO_MAX_SIZE (128 * 1024 * 1024)
++
++
++static int64_t aligned_pread(int fd, void *buf, int64_t count, int64_t offset)
++{
++ int64_t start, start_aligned;
++ int64_t 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(start, count))
++ return pread(fd, buf, count, start);
++
++ /*
++ * +- start_aligned +- end_aligned
++ * | |
++ * | +- start +- end |
++ * v v v v
++ * |----------|----------|----------|
++ * ^ ^
++ * +----- count ------+
++ * ^ ^
++ * +-------- count_aligned ---------+
++ */
++ start_aligned = RAW_IO_ALIGN(start);
++ end = start + count;
++ end_aligned = RAW_IO_ALIGN(end) +
++ (RAW_IO_ALIGNED(end, 0) ? 0 : DEVBSIZE);
++ count_aligned = end_aligned - start_aligned;
++/* exfat_debug(
++ "%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) {
++ exfat_debug("malloc(%zu) failed\n", count_aligned);
++ return -1;
++ }
++
++ /* read aligned data */
++ nr = pread(fd, 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 int64_t aligned_pwrite(int fd, void const *buf, size_t count, off_t offset)
++{
++ int64_t start, start_aligned;
++ int64_t end, end_aligned;
++ size_t count_aligned;
++ char *buf_aligned;
++ ssize_t nw;
++
++ /* short-circuit for regular files */
++ start = offset;
++ if (count > RAW_IO_MAX_SIZE)
++ count = RAW_IO_MAX_SIZE;
++ if (RAW_IO_ALIGNED(start, count))
++ return pwrite(fd, buf, count, start);
++
++ /*
++ * +- start_aligned +- end_aligned
++ * | |
++ * | +- start +- end |
++ * v v v v
++ * |----------|----------|----------|
++ * ^ ^
++ * +----- count ------+
++ * ^ ^
++ * +-------- count_aligned ---------+
++ */
++ start_aligned = RAW_IO_ALIGN(start);
++ end = start + count;
++ end_aligned = RAW_IO_ALIGN(end) +
++ (RAW_IO_ALIGNED(end, 0) ? 0 : DEVBSIZE);
++ count_aligned = end_aligned - start_aligned;
++ exfat_debug(
++ "device:%d: count = 0x%llx/0x%x, start = 0x%llx/0x%llx, end = 0x%llx/0x%llx\n",
++ fd, count, count_aligned,
++ start, start_aligned, end, end_aligned);
++
++ /* allocate buffer */
++ buf_aligned = malloc(count_aligned);
++ if (buf_aligned == NULL) {
++ exfat_error("malloc(%d) failed\n", count_aligned);
++ return -1;
++ }
++
++ /* read aligned lead-in */
++ if (pread(fd, buf_aligned, DEVBSIZE, start_aligned) != DEVBSIZE) {
++ exfat_debug("read lead-in failed\n");
++ free(buf_aligned);
++ return -1;
++ }
++
++ /* read aligned lead-out */
++ if (end != end_aligned && count_aligned > DEVBSIZE) {
++ if (pread(fd, buf_aligned + count_aligned - DEVBSIZE, DEVBSIZE, end_aligned - DEVBSIZE) != DEVBSIZE) {
++ exfat_error("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(fd, 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;
++}
++
++
+ void exfat_read_raw(void* buffer, size_t size, off_t offset, int fd)
+ {
+- if (pread(fd, buffer, size, offset) != size)
++ if (aligned_pread(fd, buffer, size, offset) != size)
+ exfat_bug("failed to read %zu bytes from file at %"PRIu64, size,
+ (uint64_t) offset);
+ }
+
+ void exfat_write_raw(const void* buffer, size_t size, off_t offset, int fd)
+ {
+- if (pwrite(fd, buffer, size, offset) != size)
++ if (aligned_pwrite(fd, buffer, size, offset) != size)
+ exfat_bug("failed to write %zu bytes to file at %"PRIu64, size,
+ (uint64_t) offset);
+ }
diff --git a/sysutils/fusefs-exfat/pkg-descr b/sysutils/fusefs-exfat/pkg-descr
new file mode 100644
index 000000000000..aa98feb129c0
--- /dev/null
+++ b/sysutils/fusefs-exfat/pkg-descr
@@ -0,0 +1,6 @@
+exfat-fuse is a free exFAT file system implementation with write support.
+exFAT is a simple file system created by Microsoft. It is intended to
+replace FAT32 removing some of it's limitations. exFAT is a standard FS for
+SDXC memory cards.
+
+WWW: http://code.google.com/p/exfat/