* [gentoo-commits] gentoo-x86 commit in sys-fs/ntfs3g/files: ntfs3g-2014.2.15-dont-put-things-in-root.patch ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch ntfs3g-2014.2.15-implement-fstrim.patch
@ 2015-01-29 8:20 Patrick McLean (chutzpah)
0 siblings, 0 replies; only message in thread
From: Patrick McLean (chutzpah) @ 2015-01-29 8:20 UTC (permalink / raw
To: gentoo-commits
chutzpah 15/01/29 08:20:05
Added: ntfs3g-2014.2.15-dont-put-things-in-root.patch
ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch
ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch
ntfs3g-2014.2.15-implement-fstrim.patch
Log:
Revision bump, add upstream patches to support fstrim. Make sure everything is in /usr/{s,}bin rather than making some symlinks in /{s,}bin. Set LD to make sure to use the bfd linker, even when the system linker is set to gold (bug #450024)
(Portage version: 2.2.15/cvs/Linux x86_64, signed Manifest commit with key 0xE3F69979BB4B8928DA78E3D17CBF44EF)
Revision Changes Path
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-dont-put-things-in-root.patch
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-dont-put-things-in-root.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-dont-put-things-in-root.patch?rev=1.1&content-type=text/plain
Index: ntfs3g-2014.2.15-dont-put-things-in-root.patch
===================================================================
diff -ur ntfs-3g_ntfsprogs-2014.2.15.orig/ntfsprogs/Makefile.am ntfs-3g_ntfsprogs-2014.2.15/ntfsprogs/Makefile.am
--- ntfs-3g_ntfsprogs-2014.2.15.orig/ntfsprogs/Makefile.am 2015-01-29 00:12:51.786936314 -0800
+++ ntfs-3g_ntfsprogs-2014.2.15/ntfsprogs/Makefile.am 2015-01-29 00:13:59.156442369 -0800
@@ -140,8 +140,7 @@
# mkfs.ntfs[.8] hard link
install-exec-hook:
- $(INSTALL) -d $(DESTDIR)/sbin
- $(LN_S) -f $(sbindir)/mkntfs $(DESTDIR)/sbin/mkfs.ntfs
+ $(LN_S) -f mkntfs $(DESTDIR)/$(sbindir)/mkfs.ntfs
install-data-hook:
$(INSTALL) -d $(DESTDIR)$(man8dir)
diff -ur ntfs-3g_ntfsprogs-2014.2.15.orig/src/Makefile.am ntfs-3g_ntfsprogs-2014.2.15/src/Makefile.am
--- ntfs-3g_ntfsprogs-2014.2.15.orig/src/Makefile.am 2015-01-29 00:12:51.789936248 -0800
+++ ntfs-3g_ntfsprogs-2014.2.15/src/Makefile.am 2015-01-29 00:14:00.570411008 -0800
@@ -68,9 +68,8 @@
if ENABLE_MOUNT_HELPER
install-exec-local: install-rootbinPROGRAMS
- $(MKDIR_P) "$(DESTDIR)/sbin"
- $(LN_S) -f "$(rootbindir)/ntfs-3g" "$(DESTDIR)/sbin/mount.ntfs-3g"
- $(LN_S) -f "$(rootbindir)/lowntfs-3g" "$(DESTDIR)/sbin/mount.lowntfs-3g"
+ $(LN_S) -f "../bin/ntfs-3g" "$(DESTDIR)/$(sbindir)/mount.ntfs-3g"
+ $(LN_S) -f "../bin/lowntfs-3g" "$(DESTDIR)/$(sbindir)/mount.lowntfs-3g"
endif
install-data-local: install-man8
@@ -80,7 +79,7 @@
uninstall-local:
$(RM) -f "$(DESTDIR)$(man8dir)/mount.ntfs-3g.8"
if ENABLE_MOUNT_HELPER
- $(RM) -f "$(DESTDIR)/sbin/mount.ntfs-3g" "$(DESTDIR)/sbin/mount.lowntfs-3g"
+ $(RM) -f "$(DESTDIR)/$(sbindir)/mount.ntfs-3g" "$(DESTDIR)/$(sbindir)/mount.lowntfs-3g"
endif
endif # ENABLE_NTFS_3G
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch?rev=1.1&content-type=text/plain
Index: ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch
===================================================================
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" },
};
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch?rev=1.1&content-type=text/plain
Index: ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch
===================================================================
From c26a519da1ed182e7cfd67e7a353932dda53d811 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= <jpandre@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
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch?rev=1.1&content-type=text/plain
Index: ntfs3g-2014.2.15-implement-fstrim.patch
===================================================================
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)
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-01-29 8:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-29 8:20 [gentoo-commits] gentoo-x86 commit in sys-fs/ntfs3g/files: ntfs3g-2014.2.15-dont-put-things-in-root.patch ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch ntfs3g-2014.2.15-implement-fstrim.patch Patrick McLean (chutzpah)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox