[ntfs-3g/el6] update to modern build

Tom Callaway spot at fedoraproject.org
Wed Oct 22 01:52:21 UTC 2014


commit 8980a73201689e5f0431d3ddfc84f1b0b777afba
Author: Tom Callaway <spot at fedoraproject.org>
Date:   Tue Oct 21 21:52:21 2014 -0400

    update to modern build

 0001-Fixed-fstrim-8-applied-to-partitions.patch    |  217 +++++++
 0001-Upgraded-fuse-lite-to-support-ioctls.patch    |  610 ++++++++++++++++++
 0002-Implemented-fstrim-8.patch                    |  648 ++++++++++++++++++++
 ntfs-3g.spec                                       |  222 +++++---
 ...-2011.10.9-RC-ntfsck-unsupported-return-0.patch |   16 +
 sources                                            |    2 +-
 6 files changed, 1634 insertions(+), 81 deletions(-)
---
diff --git a/0001-Fixed-fstrim-8-applied-to-partitions.patch b/0001-Fixed-fstrim-8-applied-to-partitions.patch
new file mode 100644
index 0000000..b67cb71
--- /dev/null
+++ b/0001-Fixed-fstrim-8-applied-to-partitions.patch
@@ -0,0 +1,217 @@
+From c26a519da1ed182e7cfd67e7a353932dda53d811 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= <jpandre at users.sourceforge.net>
+Date: Mon, 4 Aug 2014 17:39:50 +0200
+Subject: [PATCH] Fixed fstrim(8) applied to partitions
+
+The new way goes via /sys/dev/block/MAJOR:MINOR to map partitions to
+devices and get discard parameters of the parent device. It also ensures
+that the partition is aligned to the discard block size.
+
+Contributed by Richard W.M. Jones
+---
+ libntfs-3g/ioctl.c | 140 ++++++++++++++++++++++++++---------------------------
+ 1 file changed, 68 insertions(+), 72 deletions(-)
+
+diff --git a/libntfs-3g/ioctl.c b/libntfs-3g/ioctl.c
+index bbbceb9..eb7c8e7 100644
+--- a/libntfs-3g/ioctl.c
++++ b/libntfs-3g/ioctl.c
+@@ -66,8 +66,6 @@
+ #include <linux/fs.h>
+ #endif
+ 
+-#include <dirent.h>
+-
+ #include "compat.h"
+ #include "debug.h"
+ #include "bitmap.h"
+@@ -135,17 +133,14 @@ static int read_u64(const char *path, u64 *n)
+ }
+ 
+ /* Find discard limits for current backing device.
+- * XXX Kernel makes this a pain in the neck.
+  */
+-static int fstrim_limits(ntfs_volume *vol, u64 *discard_granularity,
++static int fstrim_limits(ntfs_volume *vol,
++			u64 *discard_alignment,
++			u64 *discard_granularity,
+ 			u64 *discard_max_bytes)
+ {
+ 	struct stat statbuf;
+-	DIR *dir;
+-	struct dirent *d;
+-	char path[80];
+-	char line[64];
+-	char dev[64];
++	char path1[80], path2[80];
+ 	int ret;
+ 
+ 	/* Stat the backing device.  Caller has ensured it is a block device. */
+@@ -155,82 +150,78 @@ static int fstrim_limits(ntfs_volume *vol, u64 *discard_granularity,
+ 		return -errno;
+ 	}
+ 
+-	/* Now look for a /sys/block/<dev>/dev file which contains
+-	 * "major:minor\n".
++	/* For whole devices,
++	 * /sys/dev/block/MAJOR:MINOR/discard_alignment
++	 * /sys/dev/block/MAJOR:MINOR/queue/discard_granularity
++	 * /sys/dev/block/MAJOR:MINOR/queue/discard_max_bytes
++	 * will exist.
++	 * For partitions, we also need to check the parent device:
++	 * /sys/dev/block/MAJOR:MINOR/../queue/discard_granularity
++	 * /sys/dev/block/MAJOR:MINOR/../queue/discard_max_bytes
+ 	 */
+-	snprintf(dev, sizeof dev, "%d:%d\n",
++	snprintf(path1, sizeof path1, "/sys/dev/block/%d:%d",
+ 		major(statbuf.st_rdev), minor(statbuf.st_rdev));
+ 
+-	dir = opendir("/sys/block");
+-	if (dir == NULL) {
+-		ntfs_log_debug("fstrim_limits: could not open /sys/block\n");
+-		return -errno;
++	snprintf(path2, sizeof path2, "%s/discard_alignment", path1);
++	ret = read_u64(path2, discard_alignment);
++	if (ret) {
++		if (ret != -ENOENT)
++			return ret;
++		else
++			/* We would expect this file to exist on all
++			 * modern kernels.  But for the sake of very
++			 * old kernels:
++			 */
++			goto not_found;
+ 	}
+-	for (;;) {
+-		errno = 0;
+-		d = readdir(dir);
+-		if (!d) break;
+ 
+-		snprintf(path, sizeof path, "/sys/block/%s/dev", d->d_name);
+-		ret = read_line(path, line, sizeof line);
+-		if (ret)
+-			continue;
+-		if (strcmp(line, dev) == 0)
+-			goto found;
++	snprintf(path2, sizeof path2, "%s/queue/discard_granularity", path1);
++	ret = read_u64(path2, discard_granularity);
++	if (ret) {
++		if (ret != -ENOENT)
++			return ret;
++		else {
++			snprintf(path2, sizeof path2,
++				"%s/../queue/discard_granularity", path1);
++			ret = read_u64(path2, discard_granularity);
++			if (ret) {
++				if (ret != -ENOENT)
++					return ret;
++				else
++					goto not_found;
++			}
++		}
+ 	}
+ 
+-	/* Check readdir didn't fail. */
+-	if (errno != 0) {
+-		ret = -errno;
+-		ntfs_log_debug("fstrim_limits: readdir failed\n");
+-		goto out;
++	snprintf(path2, sizeof path2, "%s/queue/discard_max_bytes", path1);
++	ret = read_u64(path2, discard_max_bytes);
++	if (ret) {
++		if (ret != -ENOENT)
++			return ret;
++		else {
++			snprintf(path2, sizeof path2,
++				"%s/../queue/discard_max_bytes", path1);
++			ret = read_u64(path2, discard_max_bytes);
++			if (ret) {
++				if (ret != -ENOENT)
++					return ret;
++				else
++					goto not_found;
++			}
++		}
+ 	}
+ 
++	return 0;
++
++not_found:
+ 	/* If we reach here then we didn't find the device.  This is
+ 	 * not an error, but set discard_max_bytes = 0 to indicate
+ 	 * that discard is not available.
+ 	 */
++	*discard_alignment = 0;
+ 	*discard_granularity = 0;
+ 	*discard_max_bytes = 0;
+-	ntfs_log_debug("fstrim_limits: /sys/block entry corresponding to device %s not found\n",
+-		vol->dev->d_name);
+-	ret = 0;
+-	goto out;
+-
+-found:
+-	/* Found the device at /sys/block/ + d->d_name */
+-	snprintf (path, sizeof path,
+-		"/sys/block/%s/queue/discard_granularity",
+-		d->d_name);
+-	ret = read_u64(path, discard_granularity);
+-	if (ret) {
+-		ntfs_log_debug("fstrim_limits: could not read %s\n", path);
+-		goto out;
+-	}
+-
+-	snprintf (path, sizeof path,
+-		"/sys/block/%s/queue/discard_max_bytes",
+-		d->d_name);
+-	ret = read_u64(path, discard_max_bytes);
+-	if (ret) {
+-		ntfs_log_debug("fstrim_limits: could not read %s\n", path);
+-		goto out;
+-	}
+-
+-	ntfs_log_debug("fstrim_limits: device %s discard granularity = %llu max_bytes = %llu\n",
+-		d->d_name,
+-		(unsigned long long) *discard_granularity,
+-		(unsigned long long) *discard_max_bytes);
+-
+-	ret = 0;
+-out:
+-	if (closedir (dir) == -1) {
+-		ret = -errno;
+-		ntfs_log_debug("fstrim_limits: closedir failed\n");
+-		return ret;
+-	}
+-
+-	return ret;
++	return 0;
+ }
+ 
+ #define FSTRIM_BUFSIZ 4096
+@@ -247,7 +238,7 @@ static int fstrim(ntfs_volume *vol, void *data)
+ 	u64 start = range->start;
+ 	u64 len = range->len;
+ 	u64 minlen = range->minlen;
+-	u64 discard_granularity, discard_max_bytes;
++	u64 discard_alignment, discard_granularity, discard_max_bytes;
+ 	u8 *buf = NULL;
+ 	LCN start_buf;
+ 	int ret;
+@@ -279,9 +270,14 @@ static int fstrim(ntfs_volume *vol, void *data)
+ 		return -EOPNOTSUPP;
+ 	}
+ 
+-	ret = fstrim_limits(vol, &discard_granularity, &discard_max_bytes);
++	ret = fstrim_limits(vol, &discard_alignment,
++			&discard_granularity, &discard_max_bytes);
+ 	if (ret)
+ 		return ret;
++	if (discard_alignment != 0) {
++		ntfs_log_debug("fstrim: backing device is not aligned for discards\n");
++		return -EOPNOTSUPP;
++	}
+ 	if (discard_granularity > vol->cluster_size) {
+ 		ntfs_log_debug("fstrim: discard granularity of backing device is larger than cluster size\n");
+ 		return -EOPNOTSUPP;
+-- 
+1.9.3
+
diff --git a/0001-Upgraded-fuse-lite-to-support-ioctls.patch b/0001-Upgraded-fuse-lite-to-support-ioctls.patch
new file mode 100644
index 0000000..0c9b7cc
--- /dev/null
+++ b/0001-Upgraded-fuse-lite-to-support-ioctls.patch
@@ -0,0 +1,610 @@
+diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_common.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_common.h
+--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_common.h	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_common.h	2014-07-31 13:47:17.401904166 +0100
+@@ -49,6 +49,22 @@
+ #endif
+ 
+ #define FUSE_CAP_BIG_WRITES	(1 << 5)
++#define FUSE_CAP_IOCTL_DIR	(1 << 11)
++
++/**
++ * Ioctl flags
++ *
++ * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
++ * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
++ * FUSE_IOCTL_RETRY: retry with new iovecs
++ * FUSE_IOCTL_DIR: is a directory 
++ */
++#define FUSE_IOCTL_COMPAT	(1 << 0)
++#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
++#define FUSE_IOCTL_RETRY	(1 << 2)
++#define FUSE_IOCTL_DIR		(1 << 4)
++
++#define FUSE_IOCTL_MAX_IOV	256
+ 
+ /**
+  * Information about open files
+diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse.h
+--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse.h	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse.h	2014-07-31 13:47:17.401904166 +0100
+@@ -420,9 +420,27 @@
+ 	 * Introduced in version 2.6
+ 	 */
+ 	int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
+- 	unsigned int flag_nullpath_ok : 1;
+  
+ 	/**
++	 * Ioctl
++	 *
++	 * flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
++	 * 64bit environment. The size and direction of data is
++	 * determined by _IOC_*() decoding of cmd. For _IOC_NONE,
++	 * data will be NULL, for _IOC_WRITE data is out area, for
++	 * _IOC_READ in area and if both are set in/out area. In all
++	 * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
++	 *
++	 * Introduced in version 2.8
++	 */
++	int (*ioctl) (const char *, int cmd, void *arg,
++		      struct fuse_file_info *, unsigned int flags, void *data); 
++
++	/*
++	 * The flags below have been discarded, they should not be used
++	 */
++ 	unsigned int flag_nullpath_ok : 1;
++	/**
+  	 * Reserved flags, don't set
+  	 */
+ 	unsigned int flag_reserved : 30;
+@@ -450,10 +468,8 @@
+ 	/** Private filesystem data */
+ 	void *private_data;
+ 
+-#ifdef POSIXACLS
+ 	/** Umask of the calling process (introduced in version 2.8) */
+ 	mode_t umask;
+-#endif
+ };
+ 
+ /* ----------------------------------------------------------- *
+@@ -601,6 +617,8 @@
+ 			const char *name);
+ int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
+ 		 uint64_t *idx);
++int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg,
++		  struct fuse_file_info *fi, unsigned int flags, void *data);
+ void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn);
+ void fuse_fs_destroy(struct fuse_fs *fs);
+ 
+diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_kernel.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_kernel.h
+--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_kernel.h	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_kernel.h	2014-07-31 13:47:17.401904166 +0100
+@@ -48,13 +48,19 @@
+ /** Version number of this interface */
+ #define FUSE_KERNEL_VERSION 7
+ 
+-/** Minor version number of this interface */
+-#ifdef POSIXACLS
+-#define FUSE_KERNEL_MINOR_VERSION 12
++/** Minor version number of this interface
++ * We introduce ourself as 7.18 (Posix ACLS : 7.12, IOCTL_DIR : 7.18)
++ * and we expect features features defined for 7.18, but not implemented
++ * here to not be triggered by ntfs-3g.
++ */
++#define FUSE_KERNEL_MINOR_VERSION 18
++
++/*
++ * For binary compatibility with old kernels we accept falling back to 7.8
++ */
++
++#define FUSE_KERNEL_MAJOR_FALLBACK 7
+ #define FUSE_KERNEL_MINOR_FALLBACK 8
+-#else
+-#define FUSE_KERNEL_MINOR_VERSION 8
+-#endif
+ 
+ /** The node ID of the root inode */
+ #define FUSE_ROOT_ID 1
+@@ -83,9 +89,7 @@
+ 	__u32	uid;
+ 	__u32	gid;
+ 	__u32	rdev;
+-#ifdef POSIXACLS
+ 	__u64 filling; /* JPA needed for minor >= 12, but meaning unknown */
+-#endif
+ };
+ 
+ struct fuse_kstatfs {
+@@ -132,11 +136,13 @@
+  * INIT request/reply flags
+  * FUSE_BIG_WRITES: allow big writes to be issued to the file system
+  * FUSE_DONT_MASK: don't apply umask to file mode on create operations
++ * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
+  */
+ #define FUSE_ASYNC_READ		(1 << 0)
+ #define FUSE_POSIX_LOCKS	(1 << 1)
+ #define FUSE_BIG_WRITES		(1 << 5)
+ #define FUSE_DONT_MASK		(1 << 6)
++#define FUSE_HAS_IOCTL_DIR	(1 << 11)
+ 
+ /**
+  * Release flags
+@@ -180,6 +186,7 @@
+ 	FUSE_INTERRUPT     = 36,
+ 	FUSE_BMAP          = 37,
+ 	FUSE_DESTROY       = 38,
++	FUSE_IOCTL         = 39,
+ };
+ 
+ /* The read buffer is required to be at least 8k, but may be much larger */
+@@ -215,10 +222,8 @@
+ struct fuse_mknod_in {
+ 	__u32	mode;
+ 	__u32	rdev;
+-#ifdef POSIXACLS
+ 	__u32	umask;
+ 	__u32	padding;
+-#endif
+ };
+ 
+ struct fuse_mkdir_in {
+@@ -255,20 +260,14 @@
+ 
+ struct fuse_open_in {
+ 	__u32	flags;
+-#ifdef POSIXACLS
+-	__u32	unused;
+-#else
+-	__u32	mode;
+-#endif
++	__u32	mode; /* unused for protocol < 7.12 */
+ };
+ 
+ struct fuse_create_in {
+ 	__u32	flags;
+ 	__u32	mode;
+-#ifdef POSIXACLS
+ 	__u32	umask;
+ 	__u32	padding;
+-#endif
+ };
+ 
+ struct fuse_open_out {
+@@ -305,11 +304,9 @@
+ 	__u64	offset;
+ 	__u32	size;
+ 	__u32	write_flags;
+-#ifdef POSIXACLS
+ 	__u64	lock_owner; /* JPA */
+ 	__u32	flags; /* JPA */
+ 	__u32	padding; /* JPA */
+-#endif
+ };
+ 
+ struct fuse_write_out {
+@@ -389,6 +386,27 @@
+ 	__u64	block;
+ };
+ 
++struct fuse_ioctl_in {
++	__u64	fh;
++	__u32	flags;
++	__u32	cmd;
++	__u64	arg;
++	__u32	in_size;
++	__u32	out_size;
++};
++
++struct fuse_ioctl_iovec {
++	__u64	base;
++	__u64	len;
++};
++
++struct fuse_ioctl_out {
++	__s32	result;
++	__u32	flags;
++	__u32	in_iovs;
++	__u32	out_iovs;
++};
++
+ struct fuse_in_header {
+ 	__u32	len;
+ 	__u32	opcode;
+diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_lowlevel.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_lowlevel.h
+--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_lowlevel.h	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_lowlevel.h	2014-07-31 13:47:17.402904167 +0100
+@@ -101,10 +101,8 @@
+ 	/** Thread ID of the calling process */
+ 	pid_t pid;
+ 
+-#ifdef POSIXACLS
+ 	/** Umask of the calling process (introduced in version 2.8) */
+ 	mode_t umask;
+-#endif
+ };
+ 
+ /* 'to_set' flags in setattr */
+@@ -805,6 +803,37 @@
+ 	 */
+ 	void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize,
+ 		      uint64_t idx);
++	/**
++	 * Ioctl
++	 *
++	 * Note: For unrestricted ioctls (not allowed for FUSE
++	 * servers), data in and out areas can be discovered by giving
++	 * iovs and setting FUSE_IOCTL_RETRY in @flags.  For
++	 * restricted ioctls, kernel prepares in/out data area
++	 * according to the information encoded in cmd.
++	 *
++	 * Introduced in version 2.8
++	 *
++	 * Valid replies:
++	 *   fuse_reply_ioctl_retry
++	 *   fuse_reply_ioctl
++	 *   fuse_reply_ioctl_iov
++	 *   fuse_reply_err
++	 *
++	 * @param req request handle
++	 * @param ino the inode number
++	 * @param cmd ioctl command
++	 * @param arg ioctl argument
++	 * @param fi file information
++	 * @param flags for FUSE_IOCTL_* flags
++	 * @param in_buf data fetched from the caller
++	 * @param in_bufsz number of fetched bytes
++	 * @param out_bufsz maximum size of output data
++	 */
++	void (*ioctl) (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
++		       struct fuse_file_info *fi, unsigned flags,
++		       const void *in_buf, size_t in_bufsz, size_t out_bufsz);
++
+ };
+ 
+ /**
+@@ -1022,6 +1051,20 @@
+ 			 const char *name, const struct stat *stbuf,
+ 			 off_t off);
+ 
++/**
++ * Reply to finish ioctl
++ *
++ * Possible requests:
++ * ioctl
++ *
++ * @param req request handle
++ * @param result result to be passed to the caller
++ * @param buf buffer containing output data
++ * @param size length of output data
++ */
++int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size);
++
++
+ /* ----------------------------------------------------------- *
+  * Utility functions					       *
+  * ----------------------------------------------------------- */
+diff -ur ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse.c ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse.c
+--- ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse.c	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse.c	2014-07-31 13:47:17.403904167 +0100
+@@ -1040,6 +1040,21 @@
+         return -ENOSYS;
+ }
+ 
++int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg,
++		  struct fuse_file_info *fi, unsigned int flags, void *data)
++{
++    fuse_get_context()->private_data = fs->user_data;
++    if (fs->op.ioctl) {
++/*
++	if (fs->debug)
++	    fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n",
++		    (unsigned long long) fi->fh, cmd, flags);
++*/
++	return fs->op.ioctl(path, cmd, arg, fi, flags, data);
++    } else
++	return -ENOSYS;
++}
++
+ static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
+ {
+     struct node *node;
+@@ -2716,6 +2731,60 @@
+         reply_err(req, err);
+ }
+ 
++static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
++			   struct fuse_file_info *llfi, unsigned int flags,
++			   const void *in_buf, size_t in_bufsz,
++			   size_t out_bufsz)
++{
++    struct fuse *f = req_fuse_prepare(req);
++    struct fuse_intr_data d;
++    struct fuse_file_info fi;
++    char *path, *out_buf = NULL;
++    int err;
++
++    err = -EPERM;
++    if (flags & FUSE_IOCTL_UNRESTRICTED)
++	goto err;
++
++    if (flags & FUSE_IOCTL_DIR)
++	get_dirhandle(llfi, &fi);
++    else
++	fi = *llfi;
++
++    if (out_bufsz) {
++	err = -ENOMEM;
++	out_buf = malloc(out_bufsz);
++	if (!out_buf)
++	    goto err;
++    }
++
++    assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
++    if (out_buf)
++	memcpy(out_buf, in_buf, in_bufsz);
++
++    path = get_path(f, ino); /* Should be get_path_nullok() */
++    if (!path) {
++	err = ENOENT;
++	goto err;
++    }
++
++    fuse_prepare_interrupt(f, req, &d);
++
++	/* Note : const qualifier dropped */
++    err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
++			out_buf ? (void*)out_buf : (void*)(uintptr_t)in_buf);
++
++    fuse_finish_interrupt(f, req, &d);
++    free(path);
++
++    fuse_reply_ioctl(req, err, out_buf, out_bufsz);
++	goto out;
++err:
++    reply_err(req, err);
++out:
++    free(out_buf);
++}
++
+ static struct fuse_lowlevel_ops fuse_path_ops = {
+     .init = fuse_lib_init,
+     .destroy = fuse_lib_destroy,
+@@ -2751,6 +2820,7 @@
+     .getlk = fuse_lib_getlk,
+     .setlk = fuse_lib_setlk,
+     .bmap = fuse_lib_bmap,
++    .ioctl = fuse_lib_ioctl,
+ };
+ 
+ struct fuse_session *fuse_get_session(struct fuse *f)
+diff -ur ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse_lowlevel.c ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse_lowlevel.c
+--- ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse_lowlevel.c	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse_lowlevel.c	2014-07-31 13:47:17.403904167 +0100
+@@ -333,12 +333,8 @@
+ 
+     memset(&arg, 0, sizeof(arg));
+     fill_entry(&arg, e);
+-#ifdef POSIXACLS
+     return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12 
+ 			? sizeof(arg) : FUSE_COMPAT_ENTRY_OUT_SIZE));
+-#else
+-    return send_reply_ok(req, &arg, sizeof(arg));
+-#endif
+ }
+ 
+ int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
+@@ -351,7 +347,6 @@
+ 
+     memset(&arg, 0, sizeof(arg));
+     fill_entry(&arg.e, e);
+-#ifdef POSIXACLS
+     if (req->f->conn.proto_minor < 12) {
+ 	fill_open((struct fuse_open_out*)
+ 		((char*)&arg + FUSE_COMPAT_ENTRY_OUT_SIZE), f);
+@@ -361,10 +356,6 @@
+     	fill_open(&arg.o, f);
+     	return send_reply_ok(req, &arg, sizeof(arg));
+     }
+-#else
+-    fill_open(&arg.o, f);
+-    return send_reply_ok(req, &arg, sizeof(arg));
+-#endif
+ }
+ 
+ int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
+@@ -377,12 +368,8 @@
+     arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout);
+     convert_stat(attr, &arg.attr);
+ 
+-#ifdef POSIXACLS
+     return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12
+ 			? sizeof(arg) : FUSE_COMPAT_FUSE_ATTR_OUT_SIZE));
+-#else
+-    return send_reply_ok(req, &arg, sizeof(arg));
+-#endif
+ }
+ 
+ int fuse_reply_readlink(fuse_req_t req, const char *linkname)
+@@ -462,6 +449,28 @@
+     return send_reply_ok(req, &arg, sizeof(arg));
+ }
+ 
++int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
++{
++    struct fuse_ioctl_out arg;
++    struct iovec iov[3];
++    size_t count = 1;
++
++    memset(&arg, 0, sizeof(arg));
++    arg.result = result;
++    iov[count].iov_base = &arg;
++    iov[count].iov_len = sizeof(arg);
++    count++;
++
++    if (size) {
++		/* Note : const qualifier dropped */
++	iov[count].iov_base = (char *)(uintptr_t) buf;
++	iov[count].iov_len = size;
++	count++;
++    }
++
++    return send_reply_iov(req, 0, iov, count);
++}
++
+ static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
+ {
+     const char *name = (const char *) inarg;
+@@ -538,11 +547,9 @@
+     const struct fuse_mknod_in *arg = (const struct fuse_mknod_in *) inarg;
+     const char *name = PARAM(arg);
+ 
+-#ifdef POSIXACLS
+     if (req->f->conn.proto_minor >= 12)
+ 	req->ctx.umask = arg->umask;
+     else
+-#endif
+ 	name = (const char *) inarg + FUSE_COMPAT_MKNOD_IN_SIZE;
+ 
+     if (req->f->op.mknod)
+@@ -555,10 +562,8 @@
+ {
+     const struct fuse_mkdir_in *arg = (const struct fuse_mkdir_in *) inarg;
+ 
+-#ifdef POSIXACLS
+     if (req->f->conn.proto_minor >= 12)
+ 	req->ctx.umask = arg->umask;
+-#endif
+ 
+     if (req->f->op.mkdir)
+         req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
+@@ -630,11 +635,9 @@
+         memset(&fi, 0, sizeof(fi));
+         fi.flags = arg->flags;
+ 
+-#ifdef POSIXACLS
+ 	if (req->f->conn.proto_minor >= 12)
+ 		req->ctx.umask = arg->umask;
+ 	else
+-#endif
+ 		name = (const char *) inarg + sizeof(struct fuse_open_in);
+ 
+ 	req->f->op.create(req, nodeid, name, arg->mode, &fi);
+@@ -682,7 +685,6 @@
+     fi.writepage = arg->write_flags & 1;
+ 
+     if (req->f->op.write) {
+-#ifdef POSIXACLS
+ 	const char *buf;
+ 
+ 	if (req->f->conn.proto_minor >= 12)
+@@ -690,9 +692,6 @@
+ 	else
+ 		buf = ((const char*)arg) + FUSE_COMPAT_WRITE_IN_SIZE;
+         req->f->op.write(req, nodeid, buf, arg->size, arg->offset, &fi);
+-#else
+-        req->f->op.write(req, nodeid, PARAM(arg), arg->size, arg->offset, &fi);
+-#endif
+     } else
+         fuse_reply_err(req, ENOSYS);
+ }
+@@ -1011,6 +1010,39 @@
+         fuse_reply_err(req, ENOSYS);
+ }
+ 
++static void do_ioctl(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
++{
++    const struct fuse_ioctl_in *arg = (const struct fuse_ioctl_in *) inarg;
++    unsigned int flags = arg->flags;
++    const void *in_buf = arg->in_size ? PARAM(arg) : NULL;
++    struct fuse_file_info fi;
++
++    if (flags & FUSE_IOCTL_DIR &&
++        !(req->f->conn.want & FUSE_CAP_IOCTL_DIR)) {
++    	fuse_reply_err(req, ENOTTY);
++    	return;
++    }
++
++    memset(&fi, 0, sizeof(fi));
++    fi.fh = arg->fh;
++
++/* TODO JPA (need req->ioctl_64bit in obscure fuse_req_t)
++// probably a 64 bit ioctl on a 32-bit cpu
++// this is to forward a request from the kernel
++    if (sizeof(void *) == 4 && req->f->conn.proto_minor >= 16 &&
++		!(flags & FUSE_IOCTL_32BIT)) {
++    	req->ioctl_64bit = 1;
++    }
++*/
++
++    if (req->f->op.ioctl)
++    	req->f->op.ioctl(req, nodeid, arg->cmd,
++    			 (void *)(uintptr_t)arg->arg, &fi, flags,
++    			 in_buf, arg->in_size, arg->out_size);
++    else
++    	fuse_reply_err(req, ENOSYS);
++}
++
+ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
+ {
+     const struct fuse_init_in *arg = (const struct fuse_init_in *) inarg;
+@@ -1047,6 +1079,8 @@
+ #endif
+ 	if (arg->flags & FUSE_BIG_WRITES)
+ 	    f->conn.capable |= FUSE_CAP_BIG_WRITES;
++	if (arg->flags & FUSE_HAS_IOCTL_DIR)
++	    f->conn.capable |= FUSE_CAP_IOCTL_DIR;
+     } else {
+         f->conn.async_read = 0;
+         f->conn.max_readahead = 0;
+@@ -1069,28 +1103,28 @@
+     memset(&outarg, 0, sizeof(outarg));
+     outarg.major = FUSE_KERNEL_VERSION;
+ 	/*
+-	 * if POSIXACLS is not set, protocol 7.8 provides a good
+-	 * compatibility with older kernel modules.
+-	 * if POSIXACLS is set, we try to use protocol 7.12 supposed
+-	 * to have the ability to process the umask conditionnally,
+-	 * but, when using an older kernel module, we fallback to 7.8
++	 * Suggest using protocol 7.18 when available, and fallback
++	 * to 7.8 when running on an old kernel.
++	 * Protocol 7.12 has the ability to process the umask
++	 * conditionnally (as needed if POSIXACLS is set)
++	 * Protocol 7.18 has the ability to process the ioctls
+ 	 */
+-#ifdef POSIXACLS
+-    if (arg->major > 7 || (arg->major == 7 && arg->minor >= 12))
++    if (arg->major > 7 || (arg->major == 7 && arg->minor >= 18)) {
+ 	    outarg.minor = FUSE_KERNEL_MINOR_VERSION;
+-    else
+-	    outarg.minor = FUSE_KERNEL_MINOR_FALLBACK;
+-#else
+-    outarg.minor = FUSE_KERNEL_MINOR_VERSION;
++	    if (f->conn.want & FUSE_CAP_IOCTL_DIR)
++		outarg.flags |= FUSE_HAS_IOCTL_DIR;
++#ifdef POSIXACLS
++	    if (f->conn.want & FUSE_CAP_DONT_MASK)
++		outarg.flags |= FUSE_DONT_MASK;
+ #endif
++    } else {
++	    outarg.major = FUSE_KERNEL_MAJOR_FALLBACK;
++	    outarg.minor = FUSE_KERNEL_MINOR_FALLBACK;
++    }
+     if (f->conn.async_read)
+         outarg.flags |= FUSE_ASYNC_READ;
+     if (f->op.getlk && f->op.setlk)
+         outarg.flags |= FUSE_POSIX_LOCKS;
+-#ifdef POSIXACLS
+-    if (f->conn.want & FUSE_CAP_DONT_MASK)
+-	outarg.flags |= FUSE_DONT_MASK;
+-#endif
+     if (f->conn.want & FUSE_CAP_BIG_WRITES)
+ 	outarg.flags |= FUSE_BIG_WRITES;
+     outarg.max_readahead = f->conn.max_readahead;
+@@ -1191,6 +1225,7 @@
+     [FUSE_CREATE]      = { do_create,      "CREATE"      },
+     [FUSE_INTERRUPT]   = { do_interrupt,   "INTERRUPT"   },
+     [FUSE_BMAP]        = { do_bmap,        "BMAP"        },
++    [FUSE_IOCTL]       = { do_ioctl,       "IOCTL"       },
+     [FUSE_DESTROY]     = { do_destroy,     "DESTROY"     },
+ };
+ 
diff --git a/0002-Implemented-fstrim-8.patch b/0002-Implemented-fstrim-8.patch
new file mode 100644
index 0000000..467f5d6
--- /dev/null
+++ b/0002-Implemented-fstrim-8.patch
@@ -0,0 +1,648 @@
+diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/configure.ac ntfs-3g_ntfsprogs-2014.2.15/configure.ac
+--- ntfs-3g_ntfsprogs-2014.2.15.old/configure.ac	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15/configure.ac	2014-07-31 13:51:24.425065808 +0100
+@@ -463,7 +463,8 @@
+ 	regex.h endian.h byteswap.h sys/byteorder.h sys/disk.h sys/endian.h \
+ 	sys/param.h sys/ioctl.h sys/mkdev.h sys/mount.h sys/stat.h sys/types.h \
+ 	sys/vfs.h sys/statvfs.h sys/sysmacros.h linux/major.h linux/fd.h \
+-	linux/hdreg.h machine/endian.h windows.h syslog.h pwd.h malloc.h])
++	linux/fs.h inttypes.h linux/hdreg.h \
++	machine/endian.h windows.h syslog.h pwd.h malloc.h])
+ 
+ # Checks for typedefs, structures, and compiler characteristics.
+ AC_HEADER_STDBOOL
+diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/include/ntfs-3g/ioctl.h ntfs-3g_ntfsprogs-2014.2.15/include/ntfs-3g/ioctl.h
+--- ntfs-3g_ntfsprogs-2014.2.15.old/include/ntfs-3g/ioctl.h	1970-01-01 01:00:00.000000000 +0100
++++ ntfs-3g_ntfsprogs-2014.2.15/include/ntfs-3g/ioctl.h	2014-07-31 13:51:24.426065810 +0100
+@@ -0,0 +1,30 @@
++/*
++ *
++ * Copyright (c) 2014 Jean-Pierre Andre
++ *
++ */
++
++/*
++ * This program 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 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
++ */
++
++#ifndef IOCTL_H
++#define IOCTL_H
++
++int ntfs_ioctl(ntfs_inode *ni, int cmd, void *arg,
++                        unsigned int flags, void *data);
++
++#endif /* IOCTL_H */
+diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/include/ntfs-3g/volume.h ntfs-3g_ntfsprogs-2014.2.15/include/ntfs-3g/volume.h
+--- ntfs-3g_ntfsprogs-2014.2.15.old/include/ntfs-3g/volume.h	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15/include/ntfs-3g/volume.h	2014-07-31 13:51:24.426065810 +0100
+@@ -36,9 +36,7 @@
+ #ifdef HAVE_SYS_PARAM_H
+ #include <sys/param.h>
+ #endif
+-#ifdef HAVE_SYS_MOUNT_H
+-#include <sys/mount.h>
+-#endif
++	/* Do not #include <sys/mount.h> here : conflicts with <linux/fs.h> */
+ #ifdef HAVE_MNTENT_H
+ #include <mntent.h>
+ #endif
+diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/ioctl.c ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/ioctl.c
+--- ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/ioctl.c	1970-01-01 01:00:00.000000000 +0100
++++ ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/ioctl.c	2014-07-31 13:51:24.427065813 +0100
+@@ -0,0 +1,382 @@
++/**
++ * ioctl.c - Processing of ioctls
++ *
++ *      This module is part of ntfs-3g library
++ *
++ * Copyright (c) 2014 Jean-Pierre Andre
++ * Copyright (c) 2014 Red Hat, Inc.
++ *
++ * 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
++ */
++
++#include "config.h"
++
++#ifdef HAVE_STDIO_H
++#include <stdio.h>
++#endif
++#ifdef HAVE_INTTYPES_H
++#include <inttypes.h>
++#endif
++#ifdef HAVE_STRING_H
++#include <string.h>
++#endif
++#ifdef HAVE_ERRNO_H
++#include <errno.h>
++#endif
++#ifdef HAVE_FCNTL_H
++#include <fcntl.h>
++#endif
++#ifdef HAVE_UNISTD_H
++#include <unistd.h>
++#endif
++#ifdef HAVE_STDLIB_H
++#include <stdlib.h>
++#endif
++#ifdef HAVE_LIMITS_H
++#include <limits.h>
++#endif
++#include <syslog.h>
++
++#ifdef HAVE_SETXATTR
++#include <sys/xattr.h>
++#endif
++
++#ifdef HAVE_SYS_TYPES_H
++#include <sys/types.h>
++#endif
++
++#ifdef HAVE_SYS_STAT_H
++#include <sys/stat.h>
++#endif
++
++#ifdef HAVE_LINUX_FS_H
++#include <linux/fs.h>
++#endif
++
++#include <dirent.h>
++
++#include "compat.h"
++#include "debug.h"
++#include "bitmap.h"
++#include "attrib.h"
++#include "inode.h"
++#include "layout.h"
++#include "volume.h"
++#include "index.h"
++#include "logging.h"
++#include "ntfstime.h"
++#include "unistr.h"
++#include "dir.h"
++#include "security.h"
++#include "ioctl.h"
++#include "misc.h"
++
++#if defined(FITRIM) && defined(BLKDISCARD)
++
++/* Issue a TRIM request to the underlying device for the given clusters. */
++static int fstrim_clusters(ntfs_volume *vol, LCN lcn, s64 length)
++{
++	struct ntfs_device *dev = vol->dev;
++	uint64_t range[2];
++
++	ntfs_log_debug("fstrim_clusters: %lld length %lld\n",
++		(long long) lcn, (long long) length);
++
++	range[0] = lcn << vol->cluster_size_bits;
++	range[1] = length << vol->cluster_size_bits;
++
++	if (dev->d_ops->ioctl(dev, BLKDISCARD, range) == -1) {
++		ntfs_log_debug("fstrim_one_cluster: ioctl failed: %m\n");
++		return -errno;
++	}
++	return 0;
++}
++
++static int read_line(const char *path, char *line, size_t max_bytes)
++{
++	FILE *fp;
++
++	fp = fopen(path, "r");
++	if (fp == NULL)
++		return -errno;
++	if (fgets(line, max_bytes, fp) == NULL) {
++		int ret = -EIO; /* fgets doesn't set errno */
++		fclose(fp);
++		return ret;
++	}
++	fclose (fp);
++	return 0;
++}
++
++static int read_u64(const char *path, u64 *n)
++{
++	char line[64];
++	int ret;
++
++	ret = read_line(path, line, sizeof line);
++	if (ret)
++		return ret;
++	if (sscanf(line, "%" SCNu64, n) != 1)
++		return -EINVAL;
++	return 0;
++}
++
++/* Find discard limits for current backing device.
++ * XXX Kernel makes this a pain in the neck.
++ */
++static int fstrim_limits(ntfs_volume *vol, u64 *discard_granularity,
++			u64 *discard_max_bytes)
++{
++	struct stat statbuf;
++	DIR *dir;
++	struct dirent *d;
++	char path[80];
++	char line[64];
++	char dev[64];
++	int ret;
++
++	/* Stat the backing device.  Caller has ensured it is a block device. */
++	if (stat(vol->dev->d_name, &statbuf) == -1) {
++		ntfs_log_debug("fstrim_limits: could not stat %s\n",
++			vol->dev->d_name);
++		return -errno;
++	}
++
++	/* Now look for a /sys/block/<dev>/dev file which contains
++	 * "major:minor\n".
++	 */
++	snprintf(dev, sizeof dev, "%d:%d\n",
++		major(statbuf.st_rdev), minor(statbuf.st_rdev));
++
++	dir = opendir("/sys/block");
++	if (dir == NULL) {
++		ntfs_log_debug("fstrim_limits: could not open /sys/block\n");
++		return -errno;
++	}
++	for (;;) {
++		errno = 0;
++		d = readdir(dir);
++		if (!d) break;
++
++		snprintf(path, sizeof path, "/sys/block/%s/dev", d->d_name);
++		ret = read_line(path, line, sizeof line);
++		if (ret)
++			continue;
++		if (strcmp(line, dev) == 0)
++			goto found;
++	}
++
++	/* Check readdir didn't fail. */
++	if (errno != 0) {
++		ret = -errno;
++		ntfs_log_debug("fstrim_limits: readdir failed\n");
++		goto out;
++	}
++
++	/* If we reach here then we didn't find the device.  This is
++	 * not an error, but set discard_max_bytes = 0 to indicate
++	 * that discard is not available.
++	 */
++	*discard_granularity = 0;
++	*discard_max_bytes = 0;
++	ntfs_log_debug("fstrim_limits: /sys/block entry corresponding to device %s not found\n",
++		vol->dev->d_name);
++	ret = 0;
++	goto out;
++
++found:
++	/* Found the device at /sys/block/ + d->d_name */
++	snprintf (path, sizeof path,
++		"/sys/block/%s/queue/discard_granularity",
++		d->d_name);
++	ret = read_u64(path, discard_granularity);
++	if (ret) {
++		ntfs_log_debug("fstrim_limits: could not read %s\n", path);
++		goto out;
++	}
++
++	snprintf (path, sizeof path,
++		"/sys/block/%s/queue/discard_max_bytes",
++		d->d_name);
++	ret = read_u64(path, discard_max_bytes);
++	if (ret) {
++		ntfs_log_debug("fstrim_limits: could not read %s\n", path);
++		goto out;
++	}
++
++	ntfs_log_debug("fstrim_limits: device %s discard granularity = %llu max_bytes = %llu\n",
++		d->d_name,
++		(unsigned long long) *discard_granularity,
++		(unsigned long long) *discard_max_bytes);
++
++	ret = 0;
++out:
++	if (closedir (dir) == -1) {
++		ret = -errno;
++		ntfs_log_debug("fstrim_limits: closedir failed\n");
++		return ret;
++	}
++
++	return ret;
++}
++
++#define FSTRIM_BUFSIZ 4096
++
++/* Trim the filesystem.
++ *
++ * Free blocks between 'start' and 'start+len-1' (both byte offsets)
++ * are found and TRIM requests are sent to the block device.  'minlen'
++ * is the minimum continguous free range to discard.
++ */
++static int fstrim(ntfs_volume *vol, void *data)
++{
++	struct fstrim_range *range = data;
++	u64 start = range->start;
++	u64 len = range->len;
++	u64 minlen = range->minlen;
++	u64 discard_granularity, discard_max_bytes;
++	u8 *buf = NULL;
++	LCN start_buf;
++	int ret;
++
++	ntfs_log_debug("fstrim: start=%llu len=%llu minlen=%llu\n",
++		(unsigned long long) start,
++		(unsigned long long) len,
++		(unsigned long long) minlen);
++
++	/* Fail if user tries to use the fstrim -o/-l/-m options.
++	 * XXX We could fix these limitations in future.
++	 */
++	if (start != 0 || len != (uint64_t)-1) {
++		ntfs_log_debug("fstrim: setting start or length is not supported\n");
++		return -EINVAL;
++	}
++	if (minlen > vol->cluster_size) {
++		ntfs_log_debug("fstrim: minlen > cluster size is not supported\n");
++		return -EINVAL;
++	}
++
++	/* Only block devices are supported.  It would be possible to
++	 * support backing files (ie. without using loop) but the
++	 * ioctls used to punch holes in files are completely
++	 * different.
++	 */
++	if (!NDevBlock(vol->dev)) {
++		ntfs_log_debug("fstrim: not supported for non-block-device\n");
++		return -EOPNOTSUPP;
++	}
++
++	ret = fstrim_limits(vol, &discard_granularity, &discard_max_bytes);
++	if (ret)
++		return ret;
++	if (discard_granularity > vol->cluster_size) {
++		ntfs_log_debug("fstrim: discard granularity of backing device is larger than cluster size\n");
++		return -EOPNOTSUPP;
++	}
++	if (discard_max_bytes == 0) {
++		ntfs_log_debug("fstrim: backing device does not support discard (discard_max_bytes == 0)\n");
++		return -EOPNOTSUPP;
++	}
++
++	/* Sync the device before doing anything. */
++	ret = ntfs_device_sync(vol->dev);
++	if (ret)
++		return ret;
++
++	/* Read through the bitmap. */
++	buf = ntfs_malloc(FSTRIM_BUFSIZ);
++	if (buf == NULL)
++		return -errno;
++	for (start_buf = 0; start_buf < vol->nr_clusters;
++	     start_buf += FSTRIM_BUFSIZ * 8) {
++		s64 count;
++		s64 br;
++		LCN end_buf, start_lcn;
++
++		/* start_buf is LCN of first cluster in the current buffer.
++		 * end_buf is LCN of last cluster + 1 in the current buffer.
++		 */
++		end_buf = start_buf + FSTRIM_BUFSIZ*8;
++		if (end_buf > vol->nr_clusters)
++			end_buf = vol->nr_clusters;
++		count = (end_buf - start_buf) / 8;
++
++		br = ntfs_attr_pread(vol->lcnbmp_na, start_buf/8, count, buf);
++		if (br != count) {
++			if (br >= 0)
++				ret = -EIO;
++			else
++				ret = -errno;
++			goto free_out;
++		}
++
++		/* Trim the clusters in large as possible blocks, but
++		 * not larger than discard_max_bytes.
++		 */
++		for (start_lcn = start_buf; start_lcn < end_buf; ++start_lcn) {
++			if (!ntfs_bit_get(buf, start_lcn-start_buf)) {
++				LCN end_lcn;
++
++				/* Cluster 'start_lcn' is not in use,
++				 * find end of this run.
++				 */
++				end_lcn = start_lcn+1;
++				while (end_lcn < end_buf &&
++					(u64) (end_lcn-start_lcn) << vol->cluster_size_bits
++					  < discard_max_bytes &&
++					!ntfs_bit_get(buf, end_lcn-start_buf))
++					end_lcn++;
++
++				ret = fstrim_clusters(vol,
++						start_lcn, end_lcn-start_lcn);
++				if (ret)
++					goto free_out;
++
++				start_lcn = end_lcn-1;
++			}
++		}
++	}
++
++	ret = 0;
++free_out:
++	free(buf);
++	return ret;
++}
++
++#endif /* FITRIM && BLKDISCARD */
++
++int ntfs_ioctl(ntfs_inode *ni, int cmd, void *arg __attribute__((unused)),
++			unsigned int flags __attribute__((unused)), void *data)
++{
++	int ret = 0;
++
++	switch (cmd) {
++#if defined(FITRIM) && defined(BLKDISCARD)
++	case FITRIM:
++		if (!ni || !data)
++			ret = -EINVAL;
++		else
++			ret = fstrim(ni->vol, data);
++		break;
++#else
++#warning FITRIM or BLKDISCARD not defined
++#endif
++	default :
++		ret = -EINVAL;
++		break;
++	}
++	return (ret);
++}
+diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/Makefile.am ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/Makefile.am
+--- ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/Makefile.am	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/Makefile.am	2014-07-31 13:51:24.426065810 +0100
+@@ -30,6 +30,7 @@
+ 	efs.c 		\
+ 	index.c 	\
+ 	inode.c 	\
++	ioctl.c 	\
+ 	lcnalloc.c 	\
+ 	logfile.c 	\
+ 	logging.c 	\
+diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/src/lowntfs-3g.c ntfs-3g_ntfsprogs-2014.2.15/src/lowntfs-3g.c
+--- ntfs-3g_ntfsprogs-2014.2.15.old/src/lowntfs-3g.c	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15/src/lowntfs-3g.c	2014-07-31 13:51:24.429065815 +0100
+@@ -81,7 +81,12 @@
+ #include <sys/dirent.h>
+ #endif /* defined(__APPLE__) || defined(__DARWIN__) */
+ 
++#ifdef HAVE_LINUX_FS_H
++#include <linux/fs.h>
++#endif
++
+ #include "compat.h"
++#include "bitmap.h"
+ #include "attrib.h"
+ #include "inode.h"
+ #include "volume.h"
+@@ -97,6 +102,7 @@
+ #include "logging.h"
+ #include "xattrs.h"
+ #include "misc.h"
++#include "ioctl.h"
+ 
+ #include "ntfs-3g_common.h"
+ 
+@@ -564,8 +570,6 @@
+ }
+ #endif /* defined(__APPLE__) || defined(__DARWIN__) */
+ 
+-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \
+-		|| (defined(__APPLE__) || defined(__DARWIN__))
+ static void ntfs_init(void *userdata __attribute__((unused)),
+ 			struct fuse_conn_info *conn)
+ {
+@@ -582,8 +586,8 @@
+ 			>= SAFE_CAPACITY_FOR_BIG_WRITES))
+ 		conn->want |= FUSE_CAP_BIG_WRITES;
+ #endif
++	conn->want |= FUSE_CAP_IOCTL_DIR;
+ }
+-#endif /* defined(FUSE_CAP_DONT_MASK) || (defined(__APPLE__) || defined(__DARWIN__)) */
+ 
+ static int ntfs_fuse_getstat(struct SECURITY_CONTEXT *scx,
+ 				ntfs_inode *ni, struct stat *stbuf)
+@@ -2573,6 +2577,48 @@
+ 		fuse_reply_err(req, 0);
+ }
+ 
++static void ntfs_fuse_ioctl(fuse_req_t req __attribute__((unused)),
++			fuse_ino_t ino __attribute__((unused)),
++			int cmd, void *arg,
++			struct fuse_file_info *fi __attribute__((unused)),
++			unsigned flags, const void *data,
++			size_t in_bufsz, size_t out_bufsz)
++{
++	ntfs_inode *ni;
++	char *buf = (char*)NULL;
++	int bufsz;
++	int ret = 0;
++
++	if (flags & FUSE_IOCTL_COMPAT) {
++		ret = -ENOSYS;
++	} else {
++		ni = ntfs_inode_open(ctx->vol, INODE(ino));
++		if (!ni) {
++			ret = -errno;
++			goto fail;
++		}
++		bufsz = (in_bufsz > out_bufsz ? in_bufsz : out_bufsz);
++		if (bufsz) {
++			buf = ntfs_malloc(bufsz);
++			if (!buf) {
++				ret = ENOMEM;
++				goto fail;
++			}
++			memcpy(buf, data, in_bufsz);
++		}
++		ret = ntfs_ioctl(ni, cmd, arg, flags, buf);
++		if (ntfs_inode_close (ni))
++			set_fuse_error(&ret);
++	}
++	if (ret)
++fail :
++		fuse_reply_err(req, -ret);
++	else
++		fuse_reply_ioctl(req, 0, buf, out_bufsz);
++	if (buf)
++		free(buf);
++}
++
+ static void ntfs_fuse_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
+ 		      uint64_t vidx)
+ {
+@@ -3496,6 +3542,7 @@
+ 	.fsyncdir	= ntfs_fuse_fsync,
+ 	.bmap		= ntfs_fuse_bmap,
+ 	.destroy	= ntfs_fuse_destroy2,
++	.ioctl		= ntfs_fuse_ioctl,
+ #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
+ 	.access 	= ntfs_fuse_access,
+ #endif
+@@ -3512,10 +3559,7 @@
+ 	.setbkuptime	= ntfs_macfuse_setbkuptime,
+ 	.setchgtime	= ntfs_macfuse_setchgtime,
+ #endif /* defined(__APPLE__) || defined(__DARWIN__) */
+-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \
+-		|| (defined(__APPLE__) || defined(__DARWIN__))
+ 	.init		= ntfs_init
+-#endif
+ };
+ 
+ static int ntfs_fuse_init(void)
+diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/src/ntfs-3g.c ntfs-3g_ntfsprogs-2014.2.15/src/ntfs-3g.c
+--- ntfs-3g_ntfsprogs-2014.2.15.old/src/ntfs-3g.c	2014-02-15 14:07:52.000000000 +0000
++++ ntfs-3g_ntfsprogs-2014.2.15/src/ntfs-3g.c	2014-07-31 13:51:24.430065816 +0100
+@@ -96,6 +96,7 @@
+ #include "logging.h"
+ #include "xattrs.h"
+ #include "misc.h"
++#include "ioctl.h"
+ 
+ #include "ntfs-3g_common.h"
+ 
+@@ -636,8 +637,6 @@
+ }
+ #endif /* defined(__APPLE__) || defined(__DARWIN__) */
+ 
+-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \
+-		|| (defined(__APPLE__) || defined(__DARWIN__))
+ static void *ntfs_init(struct fuse_conn_info *conn)
+ {
+ #if defined(__APPLE__) || defined(__DARWIN__)
+@@ -653,9 +652,9 @@
+ 			>= SAFE_CAPACITY_FOR_BIG_WRITES))
+ 		conn->want |= FUSE_CAP_BIG_WRITES;
+ #endif
++	conn->want |= FUSE_CAP_IOCTL_DIR;
+ 	return NULL;
+ }
+-#endif /* defined(FUSE_CAP_DONT_MASK) || (defined(__APPLE__) || defined(__DARWIN__)) */
+ 
+ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
+ {
+@@ -2412,6 +2411,28 @@
+ 	return (ret);
+ }
+ 
++static int ntfs_fuse_ioctl(const char *path,
++			int cmd, void *arg,
++			struct fuse_file_info *fi __attribute__((unused)),
++			unsigned int flags, void *data)
++{
++	ntfs_inode *ni;
++	int ret;
++
++	if (flags & FUSE_IOCTL_COMPAT)
++		return -ENOSYS;
++
++	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
++	if (!ni)
++		return -errno;
++
++	ret = ntfs_ioctl(ni, cmd, arg, flags, data);
++
++	if (ntfs_inode_close (ni))
++		set_fuse_error(&ret);
++	return ret;
++}
++
+ static int ntfs_fuse_bmap(const char *path, size_t blocksize, uint64_t *idx)
+ {
+ 	ntfs_inode *ni;
+@@ -3335,6 +3356,7 @@
+ 	.fsyncdir	= ntfs_fuse_fsync,
+ 	.bmap		= ntfs_fuse_bmap,
+ 	.destroy        = ntfs_fuse_destroy2,
++        .ioctl		= ntfs_fuse_ioctl,
+ #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
+ 	.access		= ntfs_fuse_access,
+ 	.opendir	= ntfs_fuse_opendir,
+@@ -3352,10 +3374,7 @@
+ 	.setbkuptime	= ntfs_macfuse_setbkuptime,
+ 	.setchgtime	= ntfs_macfuse_setchgtime,
+ #endif /* defined(__APPLE__) || defined(__DARWIN__) */
+-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \
+-		|| (defined(__APPLE__) || defined(__DARWIN__))
+ 	.init		= ntfs_init
+-#endif
+ };
+ 
+ static int ntfs_fuse_init(void)
diff --git a/ntfs-3g.spec b/ntfs-3g.spec
index 706b92c..1260f76 100644
--- a/ntfs-3g.spec
+++ b/ntfs-3g.spec
@@ -7,12 +7,11 @@
 
 Name:		ntfs-3g
 Summary:	Linux NTFS userspace driver
-Version:	2011.4.12
-Release:	5%{?dist}
+Version:	2014.2.15
+Release:	6%{?dist}
 License:	GPLv2+
 Group:		System Environment/Base
 Source0:	http://tuxera.com/opensource/%{name}_ntfsprogs-%{version}%{?subver}.tgz
-Source1:	20-ntfs-config-write-policy.fdi
 URL:		http://www.ntfs-3g.org/
 %if %{with_externalfuse}
 BuildRequires:	fuse-devel
@@ -25,16 +24,19 @@ Epoch:		2
 Provides:	ntfsprogs-fuse = %{epoch}:%{version}-%{release}
 Obsoletes:	ntfsprogs-fuse
 Provides:	fuse-ntfs-3g = %{epoch}:%{version}-%{release}
-Patch0:		ntfs-3g-2011.4.12-ntfsprogs-header-fix.patch
-Patch1:		ntfs-3g_ntfsprogs-2011.4.12-enable-extras-option-full.patch
-# http://ntfs-3g.git.sourceforge.net/git/gitweb.cgi?p=ntfs-3g/ntfs-3g_ntfsprogs;a=commit;h=571dbc5784af042c94ed0f025c4d2d842c591d1f
-# https://bugzilla.redhat.com/show_bug.cgi?id=735862
-Patch2:		ntfs-3g_ntfsprogs-571dbc5784af042c94ed0f025c4d2d842c591d1f.patch
-# http://ntfs-3g.git.sourceforge.net/git/gitweb.cgi?p=ntfs-3g/ntfs-3g_ntfsprogs;a=blobdiff;f=ntfsprogs/ntfsck.c;h=0964a4de57a385308f9b5bf61b04b25812e17b7f;hp=ff6946dfe286a87e0dafd4c6a509a8b7bc69625e;hb=HEAD;hpb=0289d1a6c31942609b96fdf2c1baeb7355fee2bc
-Patch3:		ntfsprogs-ntfsck-cleanups-from-git.patch
-# http://ntfs-3g.git.sourceforge.net/git/gitweb.cgi?p=ntfs-3g/ntfs-3g_ntfsprogs;a=blobdiff;f=ntfsprogs/ntfsfix.c;h=9b3d5eeb368ff85fa6ef3c18b44c2dcc2ba5ea07;hp=97a14a59b6318c0f2baa1c7a111bde3254e42d5a;hb=HEAD;hpb=44116675cad2055b326a9ac797c5105d78896475
-# bz 711662, 723562
-Patch4:		ntfsprogs-ntfsfix-cleanups-from-git.patch
+Patch0:		ntfs-3g_ntfsprogs-2011.10.9-RC-ntfsck-unsupported-return-0.patch
+
+# Upstream patches which add fstrim support.
+# ae9aeebbbf1523f3e37221b1172cf05775ef8ec9
+Patch1:         0001-Upgraded-fuse-lite-to-support-ioctls.patch
+# f4e3f126df0a577903ec043dbcbe38e2863ce3d6
+Patch2:         0002-Implemented-fstrim-8.patch
+# c26a519da1ed182e7cfd67e7a353932dda53d811
+Patch3:         0001-Fixed-fstrim-8-applied-to-partitions.patch
+# Patch2 requires that libntfs-3g/Makefile is regenerated.  This can
+# be removed, as well as the call to autoreconf below, when we move to
+# a released version of ntfs-3g that includes the new feature.
+BuildRequires:  autoconf automake libtool
 
 %description
 NTFS-3G is a stable, open source, GPL licensed, POSIX, read/write NTFS 
@@ -53,7 +55,9 @@ Group:		Development/Libraries
 Requires:	%{name} = %{epoch}:%{version}-%{release}
 Requires:	pkgconfig
 Provides:	ntfsprogs-devel = %{epoch}:%{version}-%{release}
-Obsoletes:	ntfsprogs-devel < %{epoch}:%{version}-%{release}
+# ntfsprogs-2.0.0-17 was never built. 2.0.0-16 was the last build for that 
+# standalone package.
+Obsoletes:	ntfsprogs-devel < 2.0.0-17
 
 %description devel
 Headers and libraries for developing applications that use ntfs-3g
@@ -66,7 +70,9 @@ Group:		System Environment/Base
 Provides:	ntfsprogs-gnomevfs = %{epoch}:%{version}-%{release}
 Obsoletes:	ntfsprogs-gnomevfs
 # Needed to fix multilib issue
-Obsoletes:	ntfsprogs < %{epoch}:%{version}-%{release}
+# ntfsprogs-2.0.0-17 was never built. 2.0.0-16 was the last build for that 
+# standalone package.
+Obsoletes:	ntfsprogs < 2.0.0-17
 
 %description -n ntfsprogs
 The ntfsprogs package currently consists of a library and utilities such as 
@@ -75,12 +81,11 @@ included utilities see man 8 ntfsprogs after installation).
 
 %prep
 %setup -q -n %{name}_ntfsprogs-%{version}%{?subver}
-%patch0 -p1 -b .header-fix
-%patch1 -p1 -b .enable-extras
-%patch2 -p1 -b .735862
-%patch3 -p1 -b .fsckfixes
-%patch4 -p1 -b .ntfsfixfixes
-autoreconf -if
+%patch0 -p1 -b .unsupported
+%patch1 -p1 -b .ioctl
+%patch2 -p1 -b .fstrim
+%patch3 -p1 -b .parts
+autoreconf -i
 
 %build
 CFLAGS="$RPM_OPT_FLAGS -D_FILE_OFFSET_BITS=64"
@@ -91,28 +96,24 @@ CFLAGS="$RPM_OPT_FLAGS -D_FILE_OFFSET_BITS=64"
 	--with-fuse=external \
 %endif
 	--exec-prefix=/ \
-	--bindir=/bin \
-	--sbindir=/sbin \
 	--enable-crypto \
-	--enable-extras \
-	--libdir=/%{_lib}
+	--enable-extras 
 make %{?_smp_mflags} LIBTOOL=%{_bindir}/libtool
 
 %install
 make LIBTOOL=%{_bindir}/libtool DESTDIR=%{buildroot} install
-rm -rf %{buildroot}/%{_lib}/*.la
-rm -rf %{buildroot}/%{_lib}/*.a
+rm -rf %{buildroot}%{_libdir}/*.la
+rm -rf %{buildroot}%{_libdir}/*.a
 
-# make the symlink an actual copy to avoid confusion
-rm -rf %{buildroot}/sbin/mount.ntfs-3g
-cp -a %{buildroot}/bin/ntfs-3g %{buildroot}/sbin/mount.ntfs-3g
+rm -rf %{buildroot}/%{_sbindir}/mount.ntfs-3g
+cp -a %{buildroot}/%{_bindir}/ntfs-3g %{buildroot}/%{_sbindir}/mount.ntfs-3g
 
 # Actually make some symlinks for simplicity...
 # ... since we're obsoleting ntfsprogs-fuse
-pushd %{buildroot}/bin
+pushd %{buildroot}/%{_bindir}
 ln -s ntfs-3g ntfsmount
 popd
-pushd %{buildroot}/sbin
+pushd %{buildroot}/%{_sbindir}
 ln -s mount.ntfs-3g mount.ntfs-fuse
 # And since there is no other package in Fedora that provides an ntfs 
 # mount...
@@ -120,81 +121,142 @@ ln -s mount.ntfs-3g mount.ntfs
 # Need this for fsck to find it
 ln -s ../bin/ntfsck fsck.ntfs
 popd
-
-# Compat symlinks
-mkdir -p %{buildroot}%{_bindir}
-pushd %{buildroot}%{_bindir}
-ln -s /bin/ntfs-3g ntfs-3g
-ln -s /bin/ntfsmount ntfsmount
-popd
-
-# Put the .pc file in the right place.
-mkdir -p %{buildroot}%{_libdir}/pkgconfig/
-mv %{buildroot}/%{_lib}/pkgconfig/libntfs-3g.pc %{buildroot}%{_libdir}/pkgconfig/
+mv %{buildroot}/sbin/* %{buildroot}/%{_sbindir}
+rmdir %{buildroot}/sbin
 
 # We get this on our own, thanks.
 rm -rf %{buildroot}%{_defaultdocdir}/%{name}/README
 
-mkdir -p %{buildroot}%{_datadir}/hal/fdi/policy/10osvendor/
-cp -a %{SOURCE1} %{buildroot}%{_datadir}/hal/fdi/policy/10osvendor/
-
 %post -p /sbin/ldconfig
 %postun -p /sbin/ldconfig
 
 %files
 %doc AUTHORS ChangeLog COPYING CREDITS NEWS README
-/sbin/mount.ntfs
-%attr(754,root,root) /sbin/mount.ntfs-3g
-/sbin/mount.ntfs-fuse
-/sbin/mount.lowntfs-3g
-/bin/ntfs-3g
-/bin/ntfsmount
-/bin/ntfs-3g.probe
-/bin/ntfs-3g.secaudit
-/bin/ntfs-3g.usermap
-/bin/lowntfs-3g
+%{_sbindir}/mount.ntfs
+%attr(754,root,root) %{_sbindir}/mount.ntfs-3g
+%{_sbindir}/mount.ntfs-fuse
+%{_sbindir}/mount.lowntfs-3g
 %{_bindir}/ntfs-3g
 %{_bindir}/ntfsmount
-/%{_lib}/libntfs-3g.so.*
+%{_bindir}/ntfs-3g.probe
+%{_bindir}/ntfs-3g.secaudit
+%{_bindir}/ntfs-3g.usermap
+%{_bindir}/lowntfs-3g
+%{_bindir}/ntfs-3g
+%{_bindir}/ntfsmount
+%{_libdir}/libntfs-3g.so.*
 %{_mandir}/man8/mount.lowntfs-3g.*
 %{_mandir}/man8/mount.ntfs-3g.*
 %{_mandir}/man8/ntfs-3g*
-%{_datadir}/hal/fdi/policy/10osvendor/20-ntfs-config-write-policy.fdi
 
 %files devel
 %{_includedir}/ntfs-3g/
-/%{_lib}/libntfs-3g.so
+%{_libdir}/libntfs-3g.so
 %{_libdir}/pkgconfig/libntfs-3g.pc
 
 %files -n ntfsprogs
 %doc AUTHORS COPYING CREDITS ChangeLog NEWS README
-/bin/ntfscat
-/bin/ntfscluster
-/bin/ntfscmp
-/bin/ntfsfix
-/bin/ntfsinfo
-/bin/ntfsls
+%{_bindir}/ntfscat
+%{_bindir}/ntfscluster
+%{_bindir}/ntfscmp
+%{_bindir}/ntfsfix
+%{_bindir}/ntfsinfo
+%{_bindir}/ntfsls
 # Extras
-/bin/ntfsck
-/bin/ntfsdecrypt
-/bin/ntfsdump_logfile
-/bin/ntfsmftalloc
-/bin/ntfsmove
-/bin/ntfstruncate
-/bin/ntfswipe
-/sbin/fsck.ntfs
-/sbin/mkfs.ntfs
-/sbin/mkntfs
-/sbin/ntfsclone
-/sbin/ntfscp
-/sbin/ntfslabel
-/sbin/ntfsresize
-/sbin/ntfsundelete
+%{_bindir}/ntfsck
+%{_bindir}/ntfsdecrypt
+%{_bindir}/ntfsdump_logfile
+%{_bindir}/ntfsmftalloc
+%{_bindir}/ntfsmove
+%{_bindir}/ntfstruncate
+%{_bindir}/ntfswipe
+%{_sbindir}/fsck.ntfs
+%{_sbindir}/mkfs.ntfs
+%{_sbindir}/mkntfs
+%{_sbindir}/ntfsclone
+%{_sbindir}/ntfscp
+%{_sbindir}/ntfslabel
+%{_sbindir}/ntfsresize
+%{_sbindir}/ntfsundelete
 %{_mandir}/man8/mkntfs.8*
 %{_mandir}/man8/mkfs.ntfs.8*
 %{_mandir}/man8/ntfs[^m][^o]*.8*
+%exclude %{_mandir}/man8/ntfs-3g*
 
 %changelog
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2:2014.2.15-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Tue Aug  5 2014 Richard W.M. Jones <rjones at redhat.com> - 2:2014.2.15-5
+- Add upstream patch to fix fstrim so it works on partitions as well
+  as whole disks.
+
+* Thu Jul 31 2014 Richard W.M. Jones <rjones at redhat.com> - 2:2014.2.15-4
+- Upstream patches which add fstrim support.
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2:2014.2.15-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Thu Apr 24 2014 Tomáš Mráz <tmraz at redhat.com> - 2:2014.2.15-2
+- Rebuild for new libgcrypt
+
+* Wed Feb 26 2014 Tom Callaway <spot at fedoraproject.org> 2:2014.2.15-1
+- update to 2014.2.15
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2:2013.1.13-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Tue May 28 2013 Tom Callaway <spot at fedoraproject.org> - 2:2013.1.13-5
+- fix bug preventing reads on compressed files on windows 8 partitions (bz967301)
+
+* Mon May  6 2013 Tom Callaway <spot at fedoraproject.org> - 2:2013.1.13-4
+- apply fixes from upstream for issue with 4K sector drives (bz951603) 
+  and truncated check for Interix types on a 32-bit CPU (bz958681)
+
+* Thu Feb  7 2013 Tom Callaway <spot at fedoraproject.org> - 2:2013.1.13-3
+- drop redundant manpages from ntfsprogs subpackage
+
+* Thu Jan 31 2013 Tom Callaway <spot at fedoraproject.org> - 2:2013.1.13-2
+- drop hal files, since hal is very dead
+
+* Tue Jan 22 2013 Richard W.M. Jones <rjones at redhat.com> - 2:2013.1.13-1
+- New upstream version 2013.1.13 (RHBZ#902729).
+- Drop ntfs-3g-junction-point-fix.patch (now upstream).
+- Drop Windows 8 patches x 2 (both now upstream).
+- Remove obsolete patches from Fedora git repository.
+- Fix .gitignore file.
+
+* Mon Oct 15 2012 Tom Callaway <spot at fedoraproject.org> - 2:2012.1.15-5
+- Limit obsoletes to last ntfsprogs-* versions ( < 2.0.0-17 ) to
+  minimize yum churn (where it would obsolete itself on every upgrade)
+  BZ#863641
+
+* Thu Oct  4 2012 Tom Callaway <spot at fedoraproject.org> - 2:2012.1.15-4
+- add patches from upstream git to add a level of safety in the case where windows 8
+  leaves the NTFS filesystem in an unsafe state and Linux access could result in data loss.
+  Basically, with these patches, Linux will refuse to mount the ntfs partition. For the details
+  refer to: https://bugzilla.redhat.com/show_bug.cgi?id=859373
+
+* Sun Aug 19 2012 Tom Callaway <spot at fedoraproject.org> - 2:2012.1.15-3
+- apply upstream fix for junction points (bz849332)
+
+* Fri Jul 20 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2:2012.1.15-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Fri Feb 10 2012 Tom Callaway <spot at fedoraproject.org> 2:2012.1.15-1
+- update to 2012.1.15
+
+* Wed Feb  1 2012 Kay Sievers <kay at redhat.com> 2:2011.10.9-3
+- install everything in /usr
+  https://fedoraproject.org/wiki/Features/UsrMove
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2:2011.10.9-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Tue Oct 11 2011 Tom Callaway <spot at fedoraproject.org> - 2:2011.10.9-1
+- 2011.10.9-RC
+- patch ntfsck to return 0 instead of 1 on unsupported filesystem cases
+
 * Mon Sep 12 2011 Tom Callaway <spot at fedoraproject.org> - 2:2011.4.12-5
 - fix ntfsck symlink (thanks to Chris Smart for catching it)
 
diff --git a/ntfs-3g_ntfsprogs-2011.10.9-RC-ntfsck-unsupported-return-0.patch b/ntfs-3g_ntfsprogs-2011.10.9-RC-ntfsck-unsupported-return-0.patch
new file mode 100644
index 0000000..8fd39c6
--- /dev/null
+++ b/ntfs-3g_ntfsprogs-2011.10.9-RC-ntfsck-unsupported-return-0.patch
@@ -0,0 +1,16 @@
+diff -up ntfs-3g_ntfsprogs-2011.10.9-RC/ntfsprogs/ntfsck.c.OLD ntfs-3g_ntfsprogs-2011.10.9-RC/ntfsprogs/ntfsck.c
+--- ntfs-3g_ntfsprogs-2011.10.9-RC/ntfsprogs/ntfsck.c.OLD	2011-10-11 10:24:02.381335115 -0400
++++ ntfs-3g_ntfsprogs-2011.10.9-RC/ntfsprogs/ntfsck.c	2011-10-11 10:26:41.513559206 -0400
+@@ -877,7 +877,11 @@ int main(int argc, char **argv)
+ 	if (errors)
+ 		return 2;
+ 	if (unsupported)
+-		return 1;
++		ntfs_log_info("ntfsck was unable to run properly.\n");
++		// If we return 1 here, we fail for ntfs services fscking on boot just because
++		// ntfsck isn't smart enough to handle 99% of cases. So, we just return 0.
++		// return 1;
++		return 0;
+ 	return 0;
+ }
+ 
diff --git a/sources b/sources
index 85a757f..cc19fcf 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-9c4ce318373b15332239a77a9d2a39fe  ntfs-3g_ntfsprogs-2011.4.12.tgz
+f11d563816249d730a00498983485f3a  ntfs-3g_ntfsprogs-2014.2.15.tgz


More information about the scm-commits mailing list