summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch')
-rw-r--r--sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch648
1 files changed, 0 insertions, 648 deletions
diff --git a/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch b/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch
deleted file mode 100644
index 467f5d67493a..000000000000
--- a/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch
+++ /dev/null
@@ -1,648 +0,0 @@
-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)