1 |
chutzpah 15/01/29 08:20:05 |
2 |
|
3 |
Added: ntfs3g-2014.2.15-dont-put-things-in-root.patch |
4 |
ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch |
5 |
ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch |
6 |
ntfs3g-2014.2.15-implement-fstrim.patch |
7 |
Log: |
8 |
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) |
9 |
|
10 |
(Portage version: 2.2.15/cvs/Linux x86_64, signed Manifest commit with key 0xE3F69979BB4B8928DA78E3D17CBF44EF) |
11 |
|
12 |
Revision Changes Path |
13 |
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-dont-put-things-in-root.patch |
14 |
|
15 |
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 |
16 |
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 |
17 |
|
18 |
Index: ntfs3g-2014.2.15-dont-put-things-in-root.patch |
19 |
=================================================================== |
20 |
diff -ur ntfs-3g_ntfsprogs-2014.2.15.orig/ntfsprogs/Makefile.am ntfs-3g_ntfsprogs-2014.2.15/ntfsprogs/Makefile.am |
21 |
--- ntfs-3g_ntfsprogs-2014.2.15.orig/ntfsprogs/Makefile.am 2015-01-29 00:12:51.786936314 -0800 |
22 |
+++ ntfs-3g_ntfsprogs-2014.2.15/ntfsprogs/Makefile.am 2015-01-29 00:13:59.156442369 -0800 |
23 |
@@ -140,8 +140,7 @@ |
24 |
# mkfs.ntfs[.8] hard link |
25 |
|
26 |
install-exec-hook: |
27 |
- $(INSTALL) -d $(DESTDIR)/sbin |
28 |
- $(LN_S) -f $(sbindir)/mkntfs $(DESTDIR)/sbin/mkfs.ntfs |
29 |
+ $(LN_S) -f mkntfs $(DESTDIR)/$(sbindir)/mkfs.ntfs |
30 |
|
31 |
install-data-hook: |
32 |
$(INSTALL) -d $(DESTDIR)$(man8dir) |
33 |
diff -ur ntfs-3g_ntfsprogs-2014.2.15.orig/src/Makefile.am ntfs-3g_ntfsprogs-2014.2.15/src/Makefile.am |
34 |
--- ntfs-3g_ntfsprogs-2014.2.15.orig/src/Makefile.am 2015-01-29 00:12:51.789936248 -0800 |
35 |
+++ ntfs-3g_ntfsprogs-2014.2.15/src/Makefile.am 2015-01-29 00:14:00.570411008 -0800 |
36 |
@@ -68,9 +68,8 @@ |
37 |
|
38 |
if ENABLE_MOUNT_HELPER |
39 |
install-exec-local: install-rootbinPROGRAMS |
40 |
- $(MKDIR_P) "$(DESTDIR)/sbin" |
41 |
- $(LN_S) -f "$(rootbindir)/ntfs-3g" "$(DESTDIR)/sbin/mount.ntfs-3g" |
42 |
- $(LN_S) -f "$(rootbindir)/lowntfs-3g" "$(DESTDIR)/sbin/mount.lowntfs-3g" |
43 |
+ $(LN_S) -f "../bin/ntfs-3g" "$(DESTDIR)/$(sbindir)/mount.ntfs-3g" |
44 |
+ $(LN_S) -f "../bin/lowntfs-3g" "$(DESTDIR)/$(sbindir)/mount.lowntfs-3g" |
45 |
endif |
46 |
|
47 |
install-data-local: install-man8 |
48 |
@@ -80,7 +79,7 @@ |
49 |
uninstall-local: |
50 |
$(RM) -f "$(DESTDIR)$(man8dir)/mount.ntfs-3g.8" |
51 |
if ENABLE_MOUNT_HELPER |
52 |
- $(RM) -f "$(DESTDIR)/sbin/mount.ntfs-3g" "$(DESTDIR)/sbin/mount.lowntfs-3g" |
53 |
+ $(RM) -f "$(DESTDIR)/$(sbindir)/mount.ntfs-3g" "$(DESTDIR)/$(sbindir)/mount.lowntfs-3g" |
54 |
endif |
55 |
|
56 |
endif # ENABLE_NTFS_3G |
57 |
|
58 |
|
59 |
|
60 |
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch |
61 |
|
62 |
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 |
63 |
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 |
64 |
|
65 |
Index: ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch |
66 |
=================================================================== |
67 |
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 |
68 |
--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_common.h 2014-02-15 14:07:52.000000000 +0000 |
69 |
+++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_common.h 2014-07-31 13:47:17.401904166 +0100 |
70 |
@@ -49,6 +49,22 @@ |
71 |
#endif |
72 |
|
73 |
#define FUSE_CAP_BIG_WRITES (1 << 5) |
74 |
+#define FUSE_CAP_IOCTL_DIR (1 << 11) |
75 |
+ |
76 |
+/** |
77 |
+ * Ioctl flags |
78 |
+ * |
79 |
+ * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine |
80 |
+ * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed |
81 |
+ * FUSE_IOCTL_RETRY: retry with new iovecs |
82 |
+ * FUSE_IOCTL_DIR: is a directory |
83 |
+ */ |
84 |
+#define FUSE_IOCTL_COMPAT (1 << 0) |
85 |
+#define FUSE_IOCTL_UNRESTRICTED (1 << 1) |
86 |
+#define FUSE_IOCTL_RETRY (1 << 2) |
87 |
+#define FUSE_IOCTL_DIR (1 << 4) |
88 |
+ |
89 |
+#define FUSE_IOCTL_MAX_IOV 256 |
90 |
|
91 |
/** |
92 |
* Information about open files |
93 |
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 |
94 |
--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse.h 2014-02-15 14:07:52.000000000 +0000 |
95 |
+++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse.h 2014-07-31 13:47:17.401904166 +0100 |
96 |
@@ -420,9 +420,27 @@ |
97 |
* Introduced in version 2.6 |
98 |
*/ |
99 |
int (*bmap) (const char *, size_t blocksize, uint64_t *idx); |
100 |
- unsigned int flag_nullpath_ok : 1; |
101 |
|
102 |
/** |
103 |
+ * Ioctl |
104 |
+ * |
105 |
+ * flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in |
106 |
+ * 64bit environment. The size and direction of data is |
107 |
+ * determined by _IOC_*() decoding of cmd. For _IOC_NONE, |
108 |
+ * data will be NULL, for _IOC_WRITE data is out area, for |
109 |
+ * _IOC_READ in area and if both are set in/out area. In all |
110 |
+ * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes. |
111 |
+ * |
112 |
+ * Introduced in version 2.8 |
113 |
+ */ |
114 |
+ int (*ioctl) (const char *, int cmd, void *arg, |
115 |
+ struct fuse_file_info *, unsigned int flags, void *data); |
116 |
+ |
117 |
+ /* |
118 |
+ * The flags below have been discarded, they should not be used |
119 |
+ */ |
120 |
+ unsigned int flag_nullpath_ok : 1; |
121 |
+ /** |
122 |
* Reserved flags, don't set |
123 |
*/ |
124 |
unsigned int flag_reserved : 30; |
125 |
@@ -450,10 +468,8 @@ |
126 |
/** Private filesystem data */ |
127 |
void *private_data; |
128 |
|
129 |
-#ifdef POSIXACLS |
130 |
/** Umask of the calling process (introduced in version 2.8) */ |
131 |
mode_t umask; |
132 |
-#endif |
133 |
}; |
134 |
|
135 |
/* ----------------------------------------------------------- * |
136 |
@@ -601,6 +617,8 @@ |
137 |
const char *name); |
138 |
int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize, |
139 |
uint64_t *idx); |
140 |
+int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg, |
141 |
+ struct fuse_file_info *fi, unsigned int flags, void *data); |
142 |
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn); |
143 |
void fuse_fs_destroy(struct fuse_fs *fs); |
144 |
|
145 |
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 |
146 |
--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_kernel.h 2014-02-15 14:07:52.000000000 +0000 |
147 |
+++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_kernel.h 2014-07-31 13:47:17.401904166 +0100 |
148 |
@@ -48,13 +48,19 @@ |
149 |
/** Version number of this interface */ |
150 |
#define FUSE_KERNEL_VERSION 7 |
151 |
|
152 |
-/** Minor version number of this interface */ |
153 |
-#ifdef POSIXACLS |
154 |
-#define FUSE_KERNEL_MINOR_VERSION 12 |
155 |
+/** Minor version number of this interface |
156 |
+ * We introduce ourself as 7.18 (Posix ACLS : 7.12, IOCTL_DIR : 7.18) |
157 |
+ * and we expect features features defined for 7.18, but not implemented |
158 |
+ * here to not be triggered by ntfs-3g. |
159 |
+ */ |
160 |
+#define FUSE_KERNEL_MINOR_VERSION 18 |
161 |
+ |
162 |
+/* |
163 |
+ * For binary compatibility with old kernels we accept falling back to 7.8 |
164 |
+ */ |
165 |
+ |
166 |
+#define FUSE_KERNEL_MAJOR_FALLBACK 7 |
167 |
#define FUSE_KERNEL_MINOR_FALLBACK 8 |
168 |
-#else |
169 |
-#define FUSE_KERNEL_MINOR_VERSION 8 |
170 |
-#endif |
171 |
|
172 |
/** The node ID of the root inode */ |
173 |
#define FUSE_ROOT_ID 1 |
174 |
@@ -83,9 +89,7 @@ |
175 |
__u32 uid; |
176 |
__u32 gid; |
177 |
__u32 rdev; |
178 |
-#ifdef POSIXACLS |
179 |
__u64 filling; /* JPA needed for minor >= 12, but meaning unknown */ |
180 |
-#endif |
181 |
}; |
182 |
|
183 |
struct fuse_kstatfs { |
184 |
@@ -132,11 +136,13 @@ |
185 |
* INIT request/reply flags |
186 |
* FUSE_BIG_WRITES: allow big writes to be issued to the file system |
187 |
* FUSE_DONT_MASK: don't apply umask to file mode on create operations |
188 |
+ * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories |
189 |
*/ |
190 |
#define FUSE_ASYNC_READ (1 << 0) |
191 |
#define FUSE_POSIX_LOCKS (1 << 1) |
192 |
#define FUSE_BIG_WRITES (1 << 5) |
193 |
#define FUSE_DONT_MASK (1 << 6) |
194 |
+#define FUSE_HAS_IOCTL_DIR (1 << 11) |
195 |
|
196 |
/** |
197 |
* Release flags |
198 |
@@ -180,6 +186,7 @@ |
199 |
FUSE_INTERRUPT = 36, |
200 |
FUSE_BMAP = 37, |
201 |
FUSE_DESTROY = 38, |
202 |
+ FUSE_IOCTL = 39, |
203 |
}; |
204 |
|
205 |
/* The read buffer is required to be at least 8k, but may be much larger */ |
206 |
@@ -215,10 +222,8 @@ |
207 |
struct fuse_mknod_in { |
208 |
__u32 mode; |
209 |
__u32 rdev; |
210 |
-#ifdef POSIXACLS |
211 |
__u32 umask; |
212 |
__u32 padding; |
213 |
-#endif |
214 |
}; |
215 |
|
216 |
struct fuse_mkdir_in { |
217 |
@@ -255,20 +260,14 @@ |
218 |
|
219 |
struct fuse_open_in { |
220 |
__u32 flags; |
221 |
-#ifdef POSIXACLS |
222 |
- __u32 unused; |
223 |
-#else |
224 |
- __u32 mode; |
225 |
-#endif |
226 |
+ __u32 mode; /* unused for protocol < 7.12 */ |
227 |
}; |
228 |
|
229 |
struct fuse_create_in { |
230 |
__u32 flags; |
231 |
__u32 mode; |
232 |
-#ifdef POSIXACLS |
233 |
__u32 umask; |
234 |
__u32 padding; |
235 |
-#endif |
236 |
}; |
237 |
|
238 |
struct fuse_open_out { |
239 |
@@ -305,11 +304,9 @@ |
240 |
__u64 offset; |
241 |
__u32 size; |
242 |
__u32 write_flags; |
243 |
-#ifdef POSIXACLS |
244 |
__u64 lock_owner; /* JPA */ |
245 |
__u32 flags; /* JPA */ |
246 |
__u32 padding; /* JPA */ |
247 |
-#endif |
248 |
}; |
249 |
|
250 |
struct fuse_write_out { |
251 |
@@ -389,6 +386,27 @@ |
252 |
__u64 block; |
253 |
}; |
254 |
|
255 |
+struct fuse_ioctl_in { |
256 |
+ __u64 fh; |
257 |
+ __u32 flags; |
258 |
+ __u32 cmd; |
259 |
+ __u64 arg; |
260 |
+ __u32 in_size; |
261 |
+ __u32 out_size; |
262 |
+}; |
263 |
+ |
264 |
+struct fuse_ioctl_iovec { |
265 |
+ __u64 base; |
266 |
+ __u64 len; |
267 |
+}; |
268 |
+ |
269 |
+struct fuse_ioctl_out { |
270 |
+ __s32 result; |
271 |
+ __u32 flags; |
272 |
+ __u32 in_iovs; |
273 |
+ __u32 out_iovs; |
274 |
+}; |
275 |
+ |
276 |
struct fuse_in_header { |
277 |
__u32 len; |
278 |
__u32 opcode; |
279 |
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 |
280 |
--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_lowlevel.h 2014-02-15 14:07:52.000000000 +0000 |
281 |
+++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_lowlevel.h 2014-07-31 13:47:17.402904167 +0100 |
282 |
@@ -101,10 +101,8 @@ |
283 |
/** Thread ID of the calling process */ |
284 |
pid_t pid; |
285 |
|
286 |
-#ifdef POSIXACLS |
287 |
/** Umask of the calling process (introduced in version 2.8) */ |
288 |
mode_t umask; |
289 |
-#endif |
290 |
}; |
291 |
|
292 |
/* 'to_set' flags in setattr */ |
293 |
@@ -805,6 +803,37 @@ |
294 |
*/ |
295 |
void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize, |
296 |
uint64_t idx); |
297 |
+ /** |
298 |
+ * Ioctl |
299 |
+ * |
300 |
+ * Note: For unrestricted ioctls (not allowed for FUSE |
301 |
+ * servers), data in and out areas can be discovered by giving |
302 |
+ * iovs and setting FUSE_IOCTL_RETRY in @flags. For |
303 |
+ * restricted ioctls, kernel prepares in/out data area |
304 |
+ * according to the information encoded in cmd. |
305 |
+ * |
306 |
+ * Introduced in version 2.8 |
307 |
+ * |
308 |
+ * Valid replies: |
309 |
+ * fuse_reply_ioctl_retry |
310 |
+ * fuse_reply_ioctl |
311 |
+ * fuse_reply_ioctl_iov |
312 |
+ * fuse_reply_err |
313 |
+ * |
314 |
+ * @param req request handle |
315 |
+ * @param ino the inode number |
316 |
+ * @param cmd ioctl command |
317 |
+ * @param arg ioctl argument |
318 |
+ * @param fi file information |
319 |
+ * @param flags for FUSE_IOCTL_* flags |
320 |
+ * @param in_buf data fetched from the caller |
321 |
+ * @param in_bufsz number of fetched bytes |
322 |
+ * @param out_bufsz maximum size of output data |
323 |
+ */ |
324 |
+ void (*ioctl) (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, |
325 |
+ struct fuse_file_info *fi, unsigned flags, |
326 |
+ const void *in_buf, size_t in_bufsz, size_t out_bufsz); |
327 |
+ |
328 |
}; |
329 |
|
330 |
/** |
331 |
@@ -1022,6 +1051,20 @@ |
332 |
const char *name, const struct stat *stbuf, |
333 |
off_t off); |
334 |
|
335 |
+/** |
336 |
+ * Reply to finish ioctl |
337 |
+ * |
338 |
+ * Possible requests: |
339 |
+ * ioctl |
340 |
+ * |
341 |
+ * @param req request handle |
342 |
+ * @param result result to be passed to the caller |
343 |
+ * @param buf buffer containing output data |
344 |
+ * @param size length of output data |
345 |
+ */ |
346 |
+int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size); |
347 |
+ |
348 |
+ |
349 |
/* ----------------------------------------------------------- * |
350 |
* Utility functions * |
351 |
* ----------------------------------------------------------- */ |
352 |
diff -ur ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse.c ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse.c |
353 |
--- ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse.c 2014-02-15 14:07:52.000000000 +0000 |
354 |
+++ ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse.c 2014-07-31 13:47:17.403904167 +0100 |
355 |
@@ -1040,6 +1040,21 @@ |
356 |
return -ENOSYS; |
357 |
} |
358 |
|
359 |
+int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg, |
360 |
+ struct fuse_file_info *fi, unsigned int flags, void *data) |
361 |
+{ |
362 |
+ fuse_get_context()->private_data = fs->user_data; |
363 |
+ if (fs->op.ioctl) { |
364 |
+/* |
365 |
+ if (fs->debug) |
366 |
+ fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n", |
367 |
+ (unsigned long long) fi->fh, cmd, flags); |
368 |
+*/ |
369 |
+ return fs->op.ioctl(path, cmd, arg, fi, flags, data); |
370 |
+ } else |
371 |
+ return -ENOSYS; |
372 |
+} |
373 |
+ |
374 |
static int is_open(struct fuse *f, fuse_ino_t dir, const char *name) |
375 |
{ |
376 |
struct node *node; |
377 |
@@ -2716,6 +2731,60 @@ |
378 |
reply_err(req, err); |
379 |
} |
380 |
|
381 |
+static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, |
382 |
+ struct fuse_file_info *llfi, unsigned int flags, |
383 |
+ const void *in_buf, size_t in_bufsz, |
384 |
+ size_t out_bufsz) |
385 |
+{ |
386 |
+ struct fuse *f = req_fuse_prepare(req); |
387 |
+ struct fuse_intr_data d; |
388 |
+ struct fuse_file_info fi; |
389 |
+ char *path, *out_buf = NULL; |
390 |
+ int err; |
391 |
+ |
392 |
+ err = -EPERM; |
393 |
+ if (flags & FUSE_IOCTL_UNRESTRICTED) |
394 |
+ goto err; |
395 |
+ |
396 |
+ if (flags & FUSE_IOCTL_DIR) |
397 |
+ get_dirhandle(llfi, &fi); |
398 |
+ else |
399 |
+ fi = *llfi; |
400 |
+ |
401 |
+ if (out_bufsz) { |
402 |
+ err = -ENOMEM; |
403 |
+ out_buf = malloc(out_bufsz); |
404 |
+ if (!out_buf) |
405 |
+ goto err; |
406 |
+ } |
407 |
+ |
408 |
+ assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz); |
409 |
+ if (out_buf) |
410 |
+ memcpy(out_buf, in_buf, in_bufsz); |
411 |
+ |
412 |
+ path = get_path(f, ino); /* Should be get_path_nullok() */ |
413 |
+ if (!path) { |
414 |
+ err = ENOENT; |
415 |
+ goto err; |
416 |
+ } |
417 |
+ |
418 |
+ fuse_prepare_interrupt(f, req, &d); |
419 |
+ |
420 |
+ /* Note : const qualifier dropped */ |
421 |
+ err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags, |
422 |
+ out_buf ? (void*)out_buf : (void*)(uintptr_t)in_buf); |
423 |
+ |
424 |
+ fuse_finish_interrupt(f, req, &d); |
425 |
+ free(path); |
426 |
+ |
427 |
+ fuse_reply_ioctl(req, err, out_buf, out_bufsz); |
428 |
+ goto out; |
429 |
+err: |
430 |
+ reply_err(req, err); |
431 |
+out: |
432 |
+ free(out_buf); |
433 |
+} |
434 |
+ |
435 |
static struct fuse_lowlevel_ops fuse_path_ops = { |
436 |
.init = fuse_lib_init, |
437 |
.destroy = fuse_lib_destroy, |
438 |
@@ -2751,6 +2820,7 @@ |
439 |
.getlk = fuse_lib_getlk, |
440 |
.setlk = fuse_lib_setlk, |
441 |
.bmap = fuse_lib_bmap, |
442 |
+ .ioctl = fuse_lib_ioctl, |
443 |
}; |
444 |
|
445 |
struct fuse_session *fuse_get_session(struct fuse *f) |
446 |
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 |
447 |
--- ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse_lowlevel.c 2014-02-15 14:07:52.000000000 +0000 |
448 |
+++ ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse_lowlevel.c 2014-07-31 13:47:17.403904167 +0100 |
449 |
@@ -333,12 +333,8 @@ |
450 |
|
451 |
memset(&arg, 0, sizeof(arg)); |
452 |
fill_entry(&arg, e); |
453 |
-#ifdef POSIXACLS |
454 |
return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12 |
455 |
? sizeof(arg) : FUSE_COMPAT_ENTRY_OUT_SIZE)); |
456 |
-#else |
457 |
- return send_reply_ok(req, &arg, sizeof(arg)); |
458 |
-#endif |
459 |
} |
460 |
|
461 |
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, |
462 |
@@ -351,7 +347,6 @@ |
463 |
|
464 |
memset(&arg, 0, sizeof(arg)); |
465 |
fill_entry(&arg.e, e); |
466 |
-#ifdef POSIXACLS |
467 |
if (req->f->conn.proto_minor < 12) { |
468 |
fill_open((struct fuse_open_out*) |
469 |
((char*)&arg + FUSE_COMPAT_ENTRY_OUT_SIZE), f); |
470 |
@@ -361,10 +356,6 @@ |
471 |
fill_open(&arg.o, f); |
472 |
return send_reply_ok(req, &arg, sizeof(arg)); |
473 |
} |
474 |
-#else |
475 |
- fill_open(&arg.o, f); |
476 |
- return send_reply_ok(req, &arg, sizeof(arg)); |
477 |
-#endif |
478 |
} |
479 |
|
480 |
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, |
481 |
@@ -377,12 +368,8 @@ |
482 |
arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout); |
483 |
convert_stat(attr, &arg.attr); |
484 |
|
485 |
-#ifdef POSIXACLS |
486 |
return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12 |
487 |
? sizeof(arg) : FUSE_COMPAT_FUSE_ATTR_OUT_SIZE)); |
488 |
-#else |
489 |
- return send_reply_ok(req, &arg, sizeof(arg)); |
490 |
-#endif |
491 |
} |
492 |
|
493 |
int fuse_reply_readlink(fuse_req_t req, const char *linkname) |
494 |
@@ -462,6 +449,28 @@ |
495 |
return send_reply_ok(req, &arg, sizeof(arg)); |
496 |
} |
497 |
|
498 |
+int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size) |
499 |
+{ |
500 |
+ struct fuse_ioctl_out arg; |
501 |
+ struct iovec iov[3]; |
502 |
+ size_t count = 1; |
503 |
+ |
504 |
+ memset(&arg, 0, sizeof(arg)); |
505 |
+ arg.result = result; |
506 |
+ iov[count].iov_base = &arg; |
507 |
+ iov[count].iov_len = sizeof(arg); |
508 |
+ count++; |
509 |
+ |
510 |
+ if (size) { |
511 |
+ /* Note : const qualifier dropped */ |
512 |
+ iov[count].iov_base = (char *)(uintptr_t) buf; |
513 |
+ iov[count].iov_len = size; |
514 |
+ count++; |
515 |
+ } |
516 |
+ |
517 |
+ return send_reply_iov(req, 0, iov, count); |
518 |
+} |
519 |
+ |
520 |
static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) |
521 |
{ |
522 |
const char *name = (const char *) inarg; |
523 |
@@ -538,11 +547,9 @@ |
524 |
const struct fuse_mknod_in *arg = (const struct fuse_mknod_in *) inarg; |
525 |
const char *name = PARAM(arg); |
526 |
|
527 |
-#ifdef POSIXACLS |
528 |
if (req->f->conn.proto_minor >= 12) |
529 |
req->ctx.umask = arg->umask; |
530 |
else |
531 |
-#endif |
532 |
name = (const char *) inarg + FUSE_COMPAT_MKNOD_IN_SIZE; |
533 |
|
534 |
if (req->f->op.mknod) |
535 |
@@ -555,10 +562,8 @@ |
536 |
{ |
537 |
const struct fuse_mkdir_in *arg = (const struct fuse_mkdir_in *) inarg; |
538 |
|
539 |
-#ifdef POSIXACLS |
540 |
if (req->f->conn.proto_minor >= 12) |
541 |
req->ctx.umask = arg->umask; |
542 |
-#endif |
543 |
|
544 |
if (req->f->op.mkdir) |
545 |
req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode); |
546 |
@@ -630,11 +635,9 @@ |
547 |
memset(&fi, 0, sizeof(fi)); |
548 |
fi.flags = arg->flags; |
549 |
|
550 |
-#ifdef POSIXACLS |
551 |
if (req->f->conn.proto_minor >= 12) |
552 |
req->ctx.umask = arg->umask; |
553 |
else |
554 |
-#endif |
555 |
name = (const char *) inarg + sizeof(struct fuse_open_in); |
556 |
|
557 |
req->f->op.create(req, nodeid, name, arg->mode, &fi); |
558 |
@@ -682,7 +685,6 @@ |
559 |
fi.writepage = arg->write_flags & 1; |
560 |
|
561 |
if (req->f->op.write) { |
562 |
-#ifdef POSIXACLS |
563 |
const char *buf; |
564 |
|
565 |
if (req->f->conn.proto_minor >= 12) |
566 |
@@ -690,9 +692,6 @@ |
567 |
else |
568 |
buf = ((const char*)arg) + FUSE_COMPAT_WRITE_IN_SIZE; |
569 |
req->f->op.write(req, nodeid, buf, arg->size, arg->offset, &fi); |
570 |
-#else |
571 |
- req->f->op.write(req, nodeid, PARAM(arg), arg->size, arg->offset, &fi); |
572 |
-#endif |
573 |
} else |
574 |
fuse_reply_err(req, ENOSYS); |
575 |
} |
576 |
@@ -1011,6 +1010,39 @@ |
577 |
fuse_reply_err(req, ENOSYS); |
578 |
} |
579 |
|
580 |
+static void do_ioctl(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) |
581 |
+{ |
582 |
+ const struct fuse_ioctl_in *arg = (const struct fuse_ioctl_in *) inarg; |
583 |
+ unsigned int flags = arg->flags; |
584 |
+ const void *in_buf = arg->in_size ? PARAM(arg) : NULL; |
585 |
+ struct fuse_file_info fi; |
586 |
+ |
587 |
+ if (flags & FUSE_IOCTL_DIR && |
588 |
+ !(req->f->conn.want & FUSE_CAP_IOCTL_DIR)) { |
589 |
+ fuse_reply_err(req, ENOTTY); |
590 |
+ return; |
591 |
+ } |
592 |
+ |
593 |
+ memset(&fi, 0, sizeof(fi)); |
594 |
+ fi.fh = arg->fh; |
595 |
+ |
596 |
+/* TODO JPA (need req->ioctl_64bit in obscure fuse_req_t) |
597 |
+// probably a 64 bit ioctl on a 32-bit cpu |
598 |
+// this is to forward a request from the kernel |
599 |
+ if (sizeof(void *) == 4 && req->f->conn.proto_minor >= 16 && |
600 |
+ !(flags & FUSE_IOCTL_32BIT)) { |
601 |
+ req->ioctl_64bit = 1; |
602 |
+ } |
603 |
+*/ |
604 |
+ |
605 |
+ if (req->f->op.ioctl) |
606 |
+ req->f->op.ioctl(req, nodeid, arg->cmd, |
607 |
+ (void *)(uintptr_t)arg->arg, &fi, flags, |
608 |
+ in_buf, arg->in_size, arg->out_size); |
609 |
+ else |
610 |
+ fuse_reply_err(req, ENOSYS); |
611 |
+} |
612 |
+ |
613 |
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) |
614 |
{ |
615 |
const struct fuse_init_in *arg = (const struct fuse_init_in *) inarg; |
616 |
@@ -1047,6 +1079,8 @@ |
617 |
#endif |
618 |
if (arg->flags & FUSE_BIG_WRITES) |
619 |
f->conn.capable |= FUSE_CAP_BIG_WRITES; |
620 |
+ if (arg->flags & FUSE_HAS_IOCTL_DIR) |
621 |
+ f->conn.capable |= FUSE_CAP_IOCTL_DIR; |
622 |
} else { |
623 |
f->conn.async_read = 0; |
624 |
f->conn.max_readahead = 0; |
625 |
@@ -1069,28 +1103,28 @@ |
626 |
memset(&outarg, 0, sizeof(outarg)); |
627 |
outarg.major = FUSE_KERNEL_VERSION; |
628 |
/* |
629 |
- * if POSIXACLS is not set, protocol 7.8 provides a good |
630 |
- * compatibility with older kernel modules. |
631 |
- * if POSIXACLS is set, we try to use protocol 7.12 supposed |
632 |
- * to have the ability to process the umask conditionnally, |
633 |
- * but, when using an older kernel module, we fallback to 7.8 |
634 |
+ * Suggest using protocol 7.18 when available, and fallback |
635 |
+ * to 7.8 when running on an old kernel. |
636 |
+ * Protocol 7.12 has the ability to process the umask |
637 |
+ * conditionnally (as needed if POSIXACLS is set) |
638 |
+ * Protocol 7.18 has the ability to process the ioctls |
639 |
*/ |
640 |
-#ifdef POSIXACLS |
641 |
- if (arg->major > 7 || (arg->major == 7 && arg->minor >= 12)) |
642 |
+ if (arg->major > 7 || (arg->major == 7 && arg->minor >= 18)) { |
643 |
outarg.minor = FUSE_KERNEL_MINOR_VERSION; |
644 |
- else |
645 |
- outarg.minor = FUSE_KERNEL_MINOR_FALLBACK; |
646 |
-#else |
647 |
- outarg.minor = FUSE_KERNEL_MINOR_VERSION; |
648 |
+ if (f->conn.want & FUSE_CAP_IOCTL_DIR) |
649 |
+ outarg.flags |= FUSE_HAS_IOCTL_DIR; |
650 |
+#ifdef POSIXACLS |
651 |
+ if (f->conn.want & FUSE_CAP_DONT_MASK) |
652 |
+ outarg.flags |= FUSE_DONT_MASK; |
653 |
#endif |
654 |
+ } else { |
655 |
+ outarg.major = FUSE_KERNEL_MAJOR_FALLBACK; |
656 |
+ outarg.minor = FUSE_KERNEL_MINOR_FALLBACK; |
657 |
+ } |
658 |
if (f->conn.async_read) |
659 |
outarg.flags |= FUSE_ASYNC_READ; |
660 |
if (f->op.getlk && f->op.setlk) |
661 |
outarg.flags |= FUSE_POSIX_LOCKS; |
662 |
-#ifdef POSIXACLS |
663 |
- if (f->conn.want & FUSE_CAP_DONT_MASK) |
664 |
- outarg.flags |= FUSE_DONT_MASK; |
665 |
-#endif |
666 |
if (f->conn.want & FUSE_CAP_BIG_WRITES) |
667 |
outarg.flags |= FUSE_BIG_WRITES; |
668 |
outarg.max_readahead = f->conn.max_readahead; |
669 |
@@ -1191,6 +1225,7 @@ |
670 |
[FUSE_CREATE] = { do_create, "CREATE" }, |
671 |
[FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" }, |
672 |
[FUSE_BMAP] = { do_bmap, "BMAP" }, |
673 |
+ [FUSE_IOCTL] = { do_ioctl, "IOCTL" }, |
674 |
[FUSE_DESTROY] = { do_destroy, "DESTROY" }, |
675 |
}; |
676 |
|
677 |
|
678 |
|
679 |
|
680 |
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch |
681 |
|
682 |
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 |
683 |
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 |
684 |
|
685 |
Index: ntfs3g-2014.2.15-fix-fstrim-applied-to-partitons.patch |
686 |
=================================================================== |
687 |
From c26a519da1ed182e7cfd67e7a353932dda53d811 Mon Sep 17 00:00:00 2001 |
688 |
From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= <jpandre@×××××××××××××××××.net> |
689 |
Date: Mon, 4 Aug 2014 17:39:50 +0200 |
690 |
Subject: [PATCH] Fixed fstrim(8) applied to partitions |
691 |
|
692 |
The new way goes via /sys/dev/block/MAJOR:MINOR to map partitions to |
693 |
devices and get discard parameters of the parent device. It also ensures |
694 |
that the partition is aligned to the discard block size. |
695 |
|
696 |
Contributed by Richard W.M. Jones |
697 |
--- |
698 |
libntfs-3g/ioctl.c | 140 ++++++++++++++++++++++++++--------------------------- |
699 |
1 file changed, 68 insertions(+), 72 deletions(-) |
700 |
|
701 |
diff --git a/libntfs-3g/ioctl.c b/libntfs-3g/ioctl.c |
702 |
index bbbceb9..eb7c8e7 100644 |
703 |
--- a/libntfs-3g/ioctl.c |
704 |
+++ b/libntfs-3g/ioctl.c |
705 |
@@ -66,8 +66,6 @@ |
706 |
#include <linux/fs.h> |
707 |
#endif |
708 |
|
709 |
-#include <dirent.h> |
710 |
- |
711 |
#include "compat.h" |
712 |
#include "debug.h" |
713 |
#include "bitmap.h" |
714 |
@@ -135,17 +133,14 @@ static int read_u64(const char *path, u64 *n) |
715 |
} |
716 |
|
717 |
/* Find discard limits for current backing device. |
718 |
- * XXX Kernel makes this a pain in the neck. |
719 |
*/ |
720 |
-static int fstrim_limits(ntfs_volume *vol, u64 *discard_granularity, |
721 |
+static int fstrim_limits(ntfs_volume *vol, |
722 |
+ u64 *discard_alignment, |
723 |
+ u64 *discard_granularity, |
724 |
u64 *discard_max_bytes) |
725 |
{ |
726 |
struct stat statbuf; |
727 |
- DIR *dir; |
728 |
- struct dirent *d; |
729 |
- char path[80]; |
730 |
- char line[64]; |
731 |
- char dev[64]; |
732 |
+ char path1[80], path2[80]; |
733 |
int ret; |
734 |
|
735 |
/* Stat the backing device. Caller has ensured it is a block device. */ |
736 |
@@ -155,82 +150,78 @@ static int fstrim_limits(ntfs_volume *vol, u64 *discard_granularity, |
737 |
return -errno; |
738 |
} |
739 |
|
740 |
- /* Now look for a /sys/block/<dev>/dev file which contains |
741 |
- * "major:minor\n". |
742 |
+ /* For whole devices, |
743 |
+ * /sys/dev/block/MAJOR:MINOR/discard_alignment |
744 |
+ * /sys/dev/block/MAJOR:MINOR/queue/discard_granularity |
745 |
+ * /sys/dev/block/MAJOR:MINOR/queue/discard_max_bytes |
746 |
+ * will exist. |
747 |
+ * For partitions, we also need to check the parent device: |
748 |
+ * /sys/dev/block/MAJOR:MINOR/../queue/discard_granularity |
749 |
+ * /sys/dev/block/MAJOR:MINOR/../queue/discard_max_bytes |
750 |
*/ |
751 |
- snprintf(dev, sizeof dev, "%d:%d\n", |
752 |
+ snprintf(path1, sizeof path1, "/sys/dev/block/%d:%d", |
753 |
major(statbuf.st_rdev), minor(statbuf.st_rdev)); |
754 |
|
755 |
- dir = opendir("/sys/block"); |
756 |
- if (dir == NULL) { |
757 |
- ntfs_log_debug("fstrim_limits: could not open /sys/block\n"); |
758 |
- return -errno; |
759 |
+ snprintf(path2, sizeof path2, "%s/discard_alignment", path1); |
760 |
+ ret = read_u64(path2, discard_alignment); |
761 |
+ if (ret) { |
762 |
+ if (ret != -ENOENT) |
763 |
+ return ret; |
764 |
+ else |
765 |
+ /* We would expect this file to exist on all |
766 |
+ * modern kernels. But for the sake of very |
767 |
+ * old kernels: |
768 |
+ */ |
769 |
+ goto not_found; |
770 |
} |
771 |
- for (;;) { |
772 |
- errno = 0; |
773 |
- d = readdir(dir); |
774 |
- if (!d) break; |
775 |
|
776 |
- snprintf(path, sizeof path, "/sys/block/%s/dev", d->d_name); |
777 |
- ret = read_line(path, line, sizeof line); |
778 |
- if (ret) |
779 |
- continue; |
780 |
- if (strcmp(line, dev) == 0) |
781 |
- goto found; |
782 |
+ snprintf(path2, sizeof path2, "%s/queue/discard_granularity", path1); |
783 |
+ ret = read_u64(path2, discard_granularity); |
784 |
+ if (ret) { |
785 |
+ if (ret != -ENOENT) |
786 |
+ return ret; |
787 |
+ else { |
788 |
+ snprintf(path2, sizeof path2, |
789 |
+ "%s/../queue/discard_granularity", path1); |
790 |
+ ret = read_u64(path2, discard_granularity); |
791 |
+ if (ret) { |
792 |
+ if (ret != -ENOENT) |
793 |
+ return ret; |
794 |
+ else |
795 |
+ goto not_found; |
796 |
+ } |
797 |
+ } |
798 |
} |
799 |
|
800 |
- /* Check readdir didn't fail. */ |
801 |
- if (errno != 0) { |
802 |
- ret = -errno; |
803 |
- ntfs_log_debug("fstrim_limits: readdir failed\n"); |
804 |
- goto out; |
805 |
+ snprintf(path2, sizeof path2, "%s/queue/discard_max_bytes", path1); |
806 |
+ ret = read_u64(path2, discard_max_bytes); |
807 |
+ if (ret) { |
808 |
+ if (ret != -ENOENT) |
809 |
+ return ret; |
810 |
+ else { |
811 |
+ snprintf(path2, sizeof path2, |
812 |
+ "%s/../queue/discard_max_bytes", path1); |
813 |
+ ret = read_u64(path2, discard_max_bytes); |
814 |
+ if (ret) { |
815 |
+ if (ret != -ENOENT) |
816 |
+ return ret; |
817 |
+ else |
818 |
+ goto not_found; |
819 |
+ } |
820 |
+ } |
821 |
} |
822 |
|
823 |
+ return 0; |
824 |
+ |
825 |
+not_found: |
826 |
/* If we reach here then we didn't find the device. This is |
827 |
* not an error, but set discard_max_bytes = 0 to indicate |
828 |
* that discard is not available. |
829 |
*/ |
830 |
+ *discard_alignment = 0; |
831 |
*discard_granularity = 0; |
832 |
*discard_max_bytes = 0; |
833 |
- ntfs_log_debug("fstrim_limits: /sys/block entry corresponding to device %s not found\n", |
834 |
- vol->dev->d_name); |
835 |
- ret = 0; |
836 |
- goto out; |
837 |
- |
838 |
-found: |
839 |
- /* Found the device at /sys/block/ + d->d_name */ |
840 |
- snprintf (path, sizeof path, |
841 |
- "/sys/block/%s/queue/discard_granularity", |
842 |
- d->d_name); |
843 |
- ret = read_u64(path, discard_granularity); |
844 |
- if (ret) { |
845 |
- ntfs_log_debug("fstrim_limits: could not read %s\n", path); |
846 |
- goto out; |
847 |
- } |
848 |
- |
849 |
- snprintf (path, sizeof path, |
850 |
- "/sys/block/%s/queue/discard_max_bytes", |
851 |
- d->d_name); |
852 |
- ret = read_u64(path, discard_max_bytes); |
853 |
- if (ret) { |
854 |
- ntfs_log_debug("fstrim_limits: could not read %s\n", path); |
855 |
- goto out; |
856 |
- } |
857 |
- |
858 |
- ntfs_log_debug("fstrim_limits: device %s discard granularity = %llu max_bytes = %llu\n", |
859 |
- d->d_name, |
860 |
- (unsigned long long) *discard_granularity, |
861 |
- (unsigned long long) *discard_max_bytes); |
862 |
- |
863 |
- ret = 0; |
864 |
-out: |
865 |
- if (closedir (dir) == -1) { |
866 |
- ret = -errno; |
867 |
- ntfs_log_debug("fstrim_limits: closedir failed\n"); |
868 |
- return ret; |
869 |
- } |
870 |
- |
871 |
- return ret; |
872 |
+ return 0; |
873 |
} |
874 |
|
875 |
#define FSTRIM_BUFSIZ 4096 |
876 |
@@ -247,7 +238,7 @@ static int fstrim(ntfs_volume *vol, void *data) |
877 |
u64 start = range->start; |
878 |
u64 len = range->len; |
879 |
u64 minlen = range->minlen; |
880 |
- u64 discard_granularity, discard_max_bytes; |
881 |
+ u64 discard_alignment, discard_granularity, discard_max_bytes; |
882 |
u8 *buf = NULL; |
883 |
LCN start_buf; |
884 |
int ret; |
885 |
@@ -279,9 +270,14 @@ static int fstrim(ntfs_volume *vol, void *data) |
886 |
return -EOPNOTSUPP; |
887 |
} |
888 |
|
889 |
- ret = fstrim_limits(vol, &discard_granularity, &discard_max_bytes); |
890 |
+ ret = fstrim_limits(vol, &discard_alignment, |
891 |
+ &discard_granularity, &discard_max_bytes); |
892 |
if (ret) |
893 |
return ret; |
894 |
+ if (discard_alignment != 0) { |
895 |
+ ntfs_log_debug("fstrim: backing device is not aligned for discards\n"); |
896 |
+ return -EOPNOTSUPP; |
897 |
+ } |
898 |
if (discard_granularity > vol->cluster_size) { |
899 |
ntfs_log_debug("fstrim: discard granularity of backing device is larger than cluster size\n"); |
900 |
return -EOPNOTSUPP; |
901 |
-- |
902 |
1.9.3 |
903 |
|
904 |
|
905 |
|
906 |
|
907 |
1.1 sys-fs/ntfs3g/files/ntfs3g-2014.2.15-implement-fstrim.patch |
908 |
|
909 |
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 |
910 |
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 |
911 |
|
912 |
Index: ntfs3g-2014.2.15-implement-fstrim.patch |
913 |
=================================================================== |
914 |
diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/configure.ac ntfs-3g_ntfsprogs-2014.2.15/configure.ac |
915 |
--- ntfs-3g_ntfsprogs-2014.2.15.old/configure.ac 2014-02-15 14:07:52.000000000 +0000 |
916 |
+++ ntfs-3g_ntfsprogs-2014.2.15/configure.ac 2014-07-31 13:51:24.425065808 +0100 |
917 |
@@ -463,7 +463,8 @@ |
918 |
regex.h endian.h byteswap.h sys/byteorder.h sys/disk.h sys/endian.h \ |
919 |
sys/param.h sys/ioctl.h sys/mkdev.h sys/mount.h sys/stat.h sys/types.h \ |
920 |
sys/vfs.h sys/statvfs.h sys/sysmacros.h linux/major.h linux/fd.h \ |
921 |
- linux/hdreg.h machine/endian.h windows.h syslog.h pwd.h malloc.h]) |
922 |
+ linux/fs.h inttypes.h linux/hdreg.h \ |
923 |
+ machine/endian.h windows.h syslog.h pwd.h malloc.h]) |
924 |
|
925 |
# Checks for typedefs, structures, and compiler characteristics. |
926 |
AC_HEADER_STDBOOL |
927 |
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 |
928 |
--- ntfs-3g_ntfsprogs-2014.2.15.old/include/ntfs-3g/ioctl.h 1970-01-01 01:00:00.000000000 +0100 |
929 |
+++ ntfs-3g_ntfsprogs-2014.2.15/include/ntfs-3g/ioctl.h 2014-07-31 13:51:24.426065810 +0100 |
930 |
@@ -0,0 +1,30 @@ |
931 |
+/* |
932 |
+ * |
933 |
+ * Copyright (c) 2014 Jean-Pierre Andre |
934 |
+ * |
935 |
+ */ |
936 |
+ |
937 |
+/* |
938 |
+ * This program is free software; you can redistribute it and/or modify |
939 |
+ * it under the terms of the GNU General Public License as published by |
940 |
+ * the Free Software Foundation; either version 2 of the License, or |
941 |
+ * (at your option) any later version. |
942 |
+ * |
943 |
+ * This program is distributed in the hope that it will be useful, |
944 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
945 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
946 |
+ * GNU General Public License for more details. |
947 |
+ * |
948 |
+ * You should have received a copy of the GNU General Public License |
949 |
+ * along with this program (in the main directory of the NTFS-3G |
950 |
+ * distribution in the file COPYING); if not, write to the Free Software |
951 |
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
952 |
+ */ |
953 |
+ |
954 |
+#ifndef IOCTL_H |
955 |
+#define IOCTL_H |
956 |
+ |
957 |
+int ntfs_ioctl(ntfs_inode *ni, int cmd, void *arg, |
958 |
+ unsigned int flags, void *data); |
959 |
+ |
960 |
+#endif /* IOCTL_H */ |
961 |
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 |
962 |
--- ntfs-3g_ntfsprogs-2014.2.15.old/include/ntfs-3g/volume.h 2014-02-15 14:07:52.000000000 +0000 |
963 |
+++ ntfs-3g_ntfsprogs-2014.2.15/include/ntfs-3g/volume.h 2014-07-31 13:51:24.426065810 +0100 |
964 |
@@ -36,9 +36,7 @@ |
965 |
#ifdef HAVE_SYS_PARAM_H |
966 |
#include <sys/param.h> |
967 |
#endif |
968 |
-#ifdef HAVE_SYS_MOUNT_H |
969 |
-#include <sys/mount.h> |
970 |
-#endif |
971 |
+ /* Do not #include <sys/mount.h> here : conflicts with <linux/fs.h> */ |
972 |
#ifdef HAVE_MNTENT_H |
973 |
#include <mntent.h> |
974 |
#endif |
975 |
diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/ioctl.c ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/ioctl.c |
976 |
--- ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/ioctl.c 1970-01-01 01:00:00.000000000 +0100 |
977 |
+++ ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/ioctl.c 2014-07-31 13:51:24.427065813 +0100 |
978 |
@@ -0,0 +1,382 @@ |
979 |
+/** |
980 |
+ * ioctl.c - Processing of ioctls |
981 |
+ * |
982 |
+ * This module is part of ntfs-3g library |
983 |
+ * |
984 |
+ * Copyright (c) 2014 Jean-Pierre Andre |
985 |
+ * Copyright (c) 2014 Red Hat, Inc. |
986 |
+ * |
987 |
+ * This program/include file is free software; you can redistribute it and/or |
988 |
+ * modify it under the terms of the GNU General Public License as published |
989 |
+ * by the Free Software Foundation; either version 2 of the License, or |
990 |
+ * (at your option) any later version. |
991 |
+ * |
992 |
+ * This program/include file is distributed in the hope that it will be |
993 |
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
994 |
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
995 |
+ * GNU General Public License for more details. |
996 |
+ * |
997 |
+ * You should have received a copy of the GNU General Public License |
998 |
+ * along with this program (in the main directory of the NTFS-3G |
999 |
+ * distribution in the file COPYING); if not, write to the Free Software |
1000 |
+ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1001 |
+ */ |
1002 |
+ |
1003 |
+#include "config.h" |
1004 |
+ |
1005 |
+#ifdef HAVE_STDIO_H |
1006 |
+#include <stdio.h> |
1007 |
+#endif |
1008 |
+#ifdef HAVE_INTTYPES_H |
1009 |
+#include <inttypes.h> |
1010 |
+#endif |
1011 |
+#ifdef HAVE_STRING_H |
1012 |
+#include <string.h> |
1013 |
+#endif |
1014 |
+#ifdef HAVE_ERRNO_H |
1015 |
+#include <errno.h> |
1016 |
+#endif |
1017 |
+#ifdef HAVE_FCNTL_H |
1018 |
+#include <fcntl.h> |
1019 |
+#endif |
1020 |
+#ifdef HAVE_UNISTD_H |
1021 |
+#include <unistd.h> |
1022 |
+#endif |
1023 |
+#ifdef HAVE_STDLIB_H |
1024 |
+#include <stdlib.h> |
1025 |
+#endif |
1026 |
+#ifdef HAVE_LIMITS_H |
1027 |
+#include <limits.h> |
1028 |
+#endif |
1029 |
+#include <syslog.h> |
1030 |
+ |
1031 |
+#ifdef HAVE_SETXATTR |
1032 |
+#include <sys/xattr.h> |
1033 |
+#endif |
1034 |
+ |
1035 |
+#ifdef HAVE_SYS_TYPES_H |
1036 |
+#include <sys/types.h> |
1037 |
+#endif |
1038 |
+ |
1039 |
+#ifdef HAVE_SYS_STAT_H |
1040 |
+#include <sys/stat.h> |
1041 |
+#endif |
1042 |
+ |
1043 |
+#ifdef HAVE_LINUX_FS_H |
1044 |
+#include <linux/fs.h> |
1045 |
+#endif |
1046 |
+ |
1047 |
+#include <dirent.h> |
1048 |
+ |
1049 |
+#include "compat.h" |
1050 |
+#include "debug.h" |
1051 |
+#include "bitmap.h" |
1052 |
+#include "attrib.h" |
1053 |
+#include "inode.h" |
1054 |
+#include "layout.h" |
1055 |
+#include "volume.h" |
1056 |
+#include "index.h" |
1057 |
+#include "logging.h" |
1058 |
+#include "ntfstime.h" |
1059 |
+#include "unistr.h" |
1060 |
+#include "dir.h" |
1061 |
+#include "security.h" |
1062 |
+#include "ioctl.h" |
1063 |
+#include "misc.h" |
1064 |
+ |
1065 |
+#if defined(FITRIM) && defined(BLKDISCARD) |
1066 |
+ |
1067 |
+/* Issue a TRIM request to the underlying device for the given clusters. */ |
1068 |
+static int fstrim_clusters(ntfs_volume *vol, LCN lcn, s64 length) |
1069 |
+{ |
1070 |
+ struct ntfs_device *dev = vol->dev; |
1071 |
+ uint64_t range[2]; |
1072 |
+ |
1073 |
+ ntfs_log_debug("fstrim_clusters: %lld length %lld\n", |
1074 |
+ (long long) lcn, (long long) length); |
1075 |
+ |
1076 |
+ range[0] = lcn << vol->cluster_size_bits; |
1077 |
+ range[1] = length << vol->cluster_size_bits; |
1078 |
+ |
1079 |
+ if (dev->d_ops->ioctl(dev, BLKDISCARD, range) == -1) { |
1080 |
+ ntfs_log_debug("fstrim_one_cluster: ioctl failed: %m\n"); |
1081 |
+ return -errno; |
1082 |
+ } |
1083 |
+ return 0; |
1084 |
+} |
1085 |
+ |
1086 |
+static int read_line(const char *path, char *line, size_t max_bytes) |
1087 |
+{ |
1088 |
+ FILE *fp; |
1089 |
+ |
1090 |
+ fp = fopen(path, "r"); |
1091 |
+ if (fp == NULL) |
1092 |
+ return -errno; |
1093 |
+ if (fgets(line, max_bytes, fp) == NULL) { |
1094 |
+ int ret = -EIO; /* fgets doesn't set errno */ |
1095 |
+ fclose(fp); |
1096 |
+ return ret; |
1097 |
+ } |
1098 |
+ fclose (fp); |
1099 |
+ return 0; |
1100 |
+} |
1101 |
+ |
1102 |
+static int read_u64(const char *path, u64 *n) |
1103 |
+{ |
1104 |
+ char line[64]; |
1105 |
+ int ret; |
1106 |
+ |
1107 |
+ ret = read_line(path, line, sizeof line); |
1108 |
+ if (ret) |
1109 |
+ return ret; |
1110 |
+ if (sscanf(line, "%" SCNu64, n) != 1) |
1111 |
+ return -EINVAL; |
1112 |
+ return 0; |
1113 |
+} |
1114 |
+ |
1115 |
+/* Find discard limits for current backing device. |
1116 |
+ * XXX Kernel makes this a pain in the neck. |
1117 |
+ */ |
1118 |
+static int fstrim_limits(ntfs_volume *vol, u64 *discard_granularity, |
1119 |
+ u64 *discard_max_bytes) |
1120 |
+{ |
1121 |
+ struct stat statbuf; |
1122 |
+ DIR *dir; |
1123 |
+ struct dirent *d; |
1124 |
+ char path[80]; |
1125 |
+ char line[64]; |
1126 |
+ char dev[64]; |
1127 |
+ int ret; |
1128 |
+ |
1129 |
+ /* Stat the backing device. Caller has ensured it is a block device. */ |
1130 |
+ if (stat(vol->dev->d_name, &statbuf) == -1) { |
1131 |
+ ntfs_log_debug("fstrim_limits: could not stat %s\n", |
1132 |
+ vol->dev->d_name); |
1133 |
+ return -errno; |
1134 |
+ } |
1135 |
+ |
1136 |
+ /* Now look for a /sys/block/<dev>/dev file which contains |
1137 |
+ * "major:minor\n". |
1138 |
+ */ |
1139 |
+ snprintf(dev, sizeof dev, "%d:%d\n", |
1140 |
+ major(statbuf.st_rdev), minor(statbuf.st_rdev)); |
1141 |
+ |
1142 |
+ dir = opendir("/sys/block"); |
1143 |
+ if (dir == NULL) { |
1144 |
+ ntfs_log_debug("fstrim_limits: could not open /sys/block\n"); |
1145 |
+ return -errno; |
1146 |
+ } |
1147 |
+ for (;;) { |
1148 |
+ errno = 0; |
1149 |
+ d = readdir(dir); |
1150 |
+ if (!d) break; |
1151 |
+ |
1152 |
+ snprintf(path, sizeof path, "/sys/block/%s/dev", d->d_name); |
1153 |
+ ret = read_line(path, line, sizeof line); |
1154 |
+ if (ret) |
1155 |
+ continue; |
1156 |
+ if (strcmp(line, dev) == 0) |
1157 |
+ goto found; |
1158 |
+ } |
1159 |
+ |
1160 |
+ /* Check readdir didn't fail. */ |
1161 |
+ if (errno != 0) { |
1162 |
+ ret = -errno; |
1163 |
+ ntfs_log_debug("fstrim_limits: readdir failed\n"); |
1164 |
+ goto out; |
1165 |
+ } |
1166 |
+ |
1167 |
+ /* If we reach here then we didn't find the device. This is |
1168 |
+ * not an error, but set discard_max_bytes = 0 to indicate |
1169 |
+ * that discard is not available. |
1170 |
+ */ |
1171 |
+ *discard_granularity = 0; |
1172 |
+ *discard_max_bytes = 0; |
1173 |
+ ntfs_log_debug("fstrim_limits: /sys/block entry corresponding to device %s not found\n", |
1174 |
+ vol->dev->d_name); |
1175 |
+ ret = 0; |
1176 |
+ goto out; |
1177 |
+ |
1178 |
+found: |
1179 |
+ /* Found the device at /sys/block/ + d->d_name */ |
1180 |
+ snprintf (path, sizeof path, |
1181 |
+ "/sys/block/%s/queue/discard_granularity", |
1182 |
+ d->d_name); |
1183 |
+ ret = read_u64(path, discard_granularity); |
1184 |
+ if (ret) { |
1185 |
+ ntfs_log_debug("fstrim_limits: could not read %s\n", path); |
1186 |
+ goto out; |
1187 |
+ } |
1188 |
+ |
1189 |
+ snprintf (path, sizeof path, |
1190 |
+ "/sys/block/%s/queue/discard_max_bytes", |
1191 |
+ d->d_name); |
1192 |
+ ret = read_u64(path, discard_max_bytes); |
1193 |
+ if (ret) { |
1194 |
+ ntfs_log_debug("fstrim_limits: could not read %s\n", path); |
1195 |
+ goto out; |
1196 |
+ } |
1197 |
+ |
1198 |
+ ntfs_log_debug("fstrim_limits: device %s discard granularity = %llu max_bytes = %llu\n", |
1199 |
+ d->d_name, |
1200 |
+ (unsigned long long) *discard_granularity, |
1201 |
+ (unsigned long long) *discard_max_bytes); |
1202 |
+ |
1203 |
+ ret = 0; |
1204 |
+out: |
1205 |
+ if (closedir (dir) == -1) { |
1206 |
+ ret = -errno; |
1207 |
+ ntfs_log_debug("fstrim_limits: closedir failed\n"); |
1208 |
+ return ret; |
1209 |
+ } |
1210 |
+ |
1211 |
+ return ret; |
1212 |
+} |
1213 |
+ |
1214 |
+#define FSTRIM_BUFSIZ 4096 |
1215 |
+ |
1216 |
+/* Trim the filesystem. |
1217 |
+ * |
1218 |
+ * Free blocks between 'start' and 'start+len-1' (both byte offsets) |
1219 |
+ * are found and TRIM requests are sent to the block device. 'minlen' |
1220 |
+ * is the minimum continguous free range to discard. |
1221 |
+ */ |
1222 |
+static int fstrim(ntfs_volume *vol, void *data) |
1223 |
+{ |
1224 |
+ struct fstrim_range *range = data; |
1225 |
+ u64 start = range->start; |
1226 |
+ u64 len = range->len; |
1227 |
+ u64 minlen = range->minlen; |
1228 |
+ u64 discard_granularity, discard_max_bytes; |
1229 |
+ u8 *buf = NULL; |
1230 |
+ LCN start_buf; |
1231 |
+ int ret; |
1232 |
+ |
1233 |
+ ntfs_log_debug("fstrim: start=%llu len=%llu minlen=%llu\n", |
1234 |
+ (unsigned long long) start, |
1235 |
+ (unsigned long long) len, |
1236 |
+ (unsigned long long) minlen); |
1237 |
+ |
1238 |
+ /* Fail if user tries to use the fstrim -o/-l/-m options. |
1239 |
+ * XXX We could fix these limitations in future. |
1240 |
+ */ |
1241 |
+ if (start != 0 || len != (uint64_t)-1) { |
1242 |
+ ntfs_log_debug("fstrim: setting start or length is not supported\n"); |
1243 |
+ return -EINVAL; |
1244 |
+ } |
1245 |
+ if (minlen > vol->cluster_size) { |
1246 |
+ ntfs_log_debug("fstrim: minlen > cluster size is not supported\n"); |
1247 |
+ return -EINVAL; |
1248 |
+ } |
1249 |
+ |
1250 |
+ /* Only block devices are supported. It would be possible to |
1251 |
+ * support backing files (ie. without using loop) but the |
1252 |
+ * ioctls used to punch holes in files are completely |
1253 |
+ * different. |
1254 |
+ */ |
1255 |
+ if (!NDevBlock(vol->dev)) { |
1256 |
+ ntfs_log_debug("fstrim: not supported for non-block-device\n"); |
1257 |
+ return -EOPNOTSUPP; |
1258 |
+ } |
1259 |
+ |
1260 |
+ ret = fstrim_limits(vol, &discard_granularity, &discard_max_bytes); |
1261 |
+ if (ret) |
1262 |
+ return ret; |
1263 |
+ if (discard_granularity > vol->cluster_size) { |
1264 |
+ ntfs_log_debug("fstrim: discard granularity of backing device is larger than cluster size\n"); |
1265 |
+ return -EOPNOTSUPP; |
1266 |
+ } |
1267 |
+ if (discard_max_bytes == 0) { |
1268 |
+ ntfs_log_debug("fstrim: backing device does not support discard (discard_max_bytes == 0)\n"); |
1269 |
+ return -EOPNOTSUPP; |
1270 |
+ } |
1271 |
+ |
1272 |
+ /* Sync the device before doing anything. */ |
1273 |
+ ret = ntfs_device_sync(vol->dev); |
1274 |
+ if (ret) |
1275 |
+ return ret; |
1276 |
+ |
1277 |
+ /* Read through the bitmap. */ |
1278 |
+ buf = ntfs_malloc(FSTRIM_BUFSIZ); |
1279 |
+ if (buf == NULL) |
1280 |
+ return -errno; |
1281 |
+ for (start_buf = 0; start_buf < vol->nr_clusters; |
1282 |
+ start_buf += FSTRIM_BUFSIZ * 8) { |
1283 |
+ s64 count; |
1284 |
+ s64 br; |
1285 |
+ LCN end_buf, start_lcn; |
1286 |
+ |
1287 |
+ /* start_buf is LCN of first cluster in the current buffer. |
1288 |
+ * end_buf is LCN of last cluster + 1 in the current buffer. |
1289 |
+ */ |
1290 |
+ end_buf = start_buf + FSTRIM_BUFSIZ*8; |
1291 |
+ if (end_buf > vol->nr_clusters) |
1292 |
+ end_buf = vol->nr_clusters; |
1293 |
+ count = (end_buf - start_buf) / 8; |
1294 |
+ |
1295 |
+ br = ntfs_attr_pread(vol->lcnbmp_na, start_buf/8, count, buf); |
1296 |
+ if (br != count) { |
1297 |
+ if (br >= 0) |
1298 |
+ ret = -EIO; |
1299 |
+ else |
1300 |
+ ret = -errno; |
1301 |
+ goto free_out; |
1302 |
+ } |
1303 |
+ |
1304 |
+ /* Trim the clusters in large as possible blocks, but |
1305 |
+ * not larger than discard_max_bytes. |
1306 |
+ */ |
1307 |
+ for (start_lcn = start_buf; start_lcn < end_buf; ++start_lcn) { |
1308 |
+ if (!ntfs_bit_get(buf, start_lcn-start_buf)) { |
1309 |
+ LCN end_lcn; |
1310 |
+ |
1311 |
+ /* Cluster 'start_lcn' is not in use, |
1312 |
+ * find end of this run. |
1313 |
+ */ |
1314 |
+ end_lcn = start_lcn+1; |
1315 |
+ while (end_lcn < end_buf && |
1316 |
+ (u64) (end_lcn-start_lcn) << vol->cluster_size_bits |
1317 |
+ < discard_max_bytes && |
1318 |
+ !ntfs_bit_get(buf, end_lcn-start_buf)) |
1319 |
+ end_lcn++; |
1320 |
+ |
1321 |
+ ret = fstrim_clusters(vol, |
1322 |
+ start_lcn, end_lcn-start_lcn); |
1323 |
+ if (ret) |
1324 |
+ goto free_out; |
1325 |
+ |
1326 |
+ start_lcn = end_lcn-1; |
1327 |
+ } |
1328 |
+ } |
1329 |
+ } |
1330 |
+ |
1331 |
+ ret = 0; |
1332 |
+free_out: |
1333 |
+ free(buf); |
1334 |
+ return ret; |
1335 |
+} |
1336 |
+ |
1337 |
+#endif /* FITRIM && BLKDISCARD */ |
1338 |
+ |
1339 |
+int ntfs_ioctl(ntfs_inode *ni, int cmd, void *arg __attribute__((unused)), |
1340 |
+ unsigned int flags __attribute__((unused)), void *data) |
1341 |
+{ |
1342 |
+ int ret = 0; |
1343 |
+ |
1344 |
+ switch (cmd) { |
1345 |
+#if defined(FITRIM) && defined(BLKDISCARD) |
1346 |
+ case FITRIM: |
1347 |
+ if (!ni || !data) |
1348 |
+ ret = -EINVAL; |
1349 |
+ else |
1350 |
+ ret = fstrim(ni->vol, data); |
1351 |
+ break; |
1352 |
+#else |
1353 |
+#warning FITRIM or BLKDISCARD not defined |
1354 |
+#endif |
1355 |
+ default : |
1356 |
+ ret = -EINVAL; |
1357 |
+ break; |
1358 |
+ } |
1359 |
+ return (ret); |
1360 |
+} |
1361 |
diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/Makefile.am ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/Makefile.am |
1362 |
--- ntfs-3g_ntfsprogs-2014.2.15.old/libntfs-3g/Makefile.am 2014-02-15 14:07:52.000000000 +0000 |
1363 |
+++ ntfs-3g_ntfsprogs-2014.2.15/libntfs-3g/Makefile.am 2014-07-31 13:51:24.426065810 +0100 |
1364 |
@@ -30,6 +30,7 @@ |
1365 |
efs.c \ |
1366 |
index.c \ |
1367 |
inode.c \ |
1368 |
+ ioctl.c \ |
1369 |
lcnalloc.c \ |
1370 |
logfile.c \ |
1371 |
logging.c \ |
1372 |
diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/src/lowntfs-3g.c ntfs-3g_ntfsprogs-2014.2.15/src/lowntfs-3g.c |
1373 |
--- ntfs-3g_ntfsprogs-2014.2.15.old/src/lowntfs-3g.c 2014-02-15 14:07:52.000000000 +0000 |
1374 |
+++ ntfs-3g_ntfsprogs-2014.2.15/src/lowntfs-3g.c 2014-07-31 13:51:24.429065815 +0100 |
1375 |
@@ -81,7 +81,12 @@ |
1376 |
#include <sys/dirent.h> |
1377 |
#endif /* defined(__APPLE__) || defined(__DARWIN__) */ |
1378 |
|
1379 |
+#ifdef HAVE_LINUX_FS_H |
1380 |
+#include <linux/fs.h> |
1381 |
+#endif |
1382 |
+ |
1383 |
#include "compat.h" |
1384 |
+#include "bitmap.h" |
1385 |
#include "attrib.h" |
1386 |
#include "inode.h" |
1387 |
#include "volume.h" |
1388 |
@@ -97,6 +102,7 @@ |
1389 |
#include "logging.h" |
1390 |
#include "xattrs.h" |
1391 |
#include "misc.h" |
1392 |
+#include "ioctl.h" |
1393 |
|
1394 |
#include "ntfs-3g_common.h" |
1395 |
|
1396 |
@@ -564,8 +570,6 @@ |
1397 |
} |
1398 |
#endif /* defined(__APPLE__) || defined(__DARWIN__) */ |
1399 |
|
1400 |
-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \ |
1401 |
- || (defined(__APPLE__) || defined(__DARWIN__)) |
1402 |
static void ntfs_init(void *userdata __attribute__((unused)), |
1403 |
struct fuse_conn_info *conn) |
1404 |
{ |
1405 |
@@ -582,8 +586,8 @@ |
1406 |
>= SAFE_CAPACITY_FOR_BIG_WRITES)) |
1407 |
conn->want |= FUSE_CAP_BIG_WRITES; |
1408 |
#endif |
1409 |
+ conn->want |= FUSE_CAP_IOCTL_DIR; |
1410 |
} |
1411 |
-#endif /* defined(FUSE_CAP_DONT_MASK) || (defined(__APPLE__) || defined(__DARWIN__)) */ |
1412 |
|
1413 |
static int ntfs_fuse_getstat(struct SECURITY_CONTEXT *scx, |
1414 |
ntfs_inode *ni, struct stat *stbuf) |
1415 |
@@ -2573,6 +2577,48 @@ |
1416 |
fuse_reply_err(req, 0); |
1417 |
} |
1418 |
|
1419 |
+static void ntfs_fuse_ioctl(fuse_req_t req __attribute__((unused)), |
1420 |
+ fuse_ino_t ino __attribute__((unused)), |
1421 |
+ int cmd, void *arg, |
1422 |
+ struct fuse_file_info *fi __attribute__((unused)), |
1423 |
+ unsigned flags, const void *data, |
1424 |
+ size_t in_bufsz, size_t out_bufsz) |
1425 |
+{ |
1426 |
+ ntfs_inode *ni; |
1427 |
+ char *buf = (char*)NULL; |
1428 |
+ int bufsz; |
1429 |
+ int ret = 0; |
1430 |
+ |
1431 |
+ if (flags & FUSE_IOCTL_COMPAT) { |
1432 |
+ ret = -ENOSYS; |
1433 |
+ } else { |
1434 |
+ ni = ntfs_inode_open(ctx->vol, INODE(ino)); |
1435 |
+ if (!ni) { |
1436 |
+ ret = -errno; |
1437 |
+ goto fail; |
1438 |
+ } |
1439 |
+ bufsz = (in_bufsz > out_bufsz ? in_bufsz : out_bufsz); |
1440 |
+ if (bufsz) { |
1441 |
+ buf = ntfs_malloc(bufsz); |
1442 |
+ if (!buf) { |
1443 |
+ ret = ENOMEM; |
1444 |
+ goto fail; |
1445 |
+ } |
1446 |
+ memcpy(buf, data, in_bufsz); |
1447 |
+ } |
1448 |
+ ret = ntfs_ioctl(ni, cmd, arg, flags, buf); |
1449 |
+ if (ntfs_inode_close (ni)) |
1450 |
+ set_fuse_error(&ret); |
1451 |
+ } |
1452 |
+ if (ret) |
1453 |
+fail : |
1454 |
+ fuse_reply_err(req, -ret); |
1455 |
+ else |
1456 |
+ fuse_reply_ioctl(req, 0, buf, out_bufsz); |
1457 |
+ if (buf) |
1458 |
+ free(buf); |
1459 |
+} |
1460 |
+ |
1461 |
static void ntfs_fuse_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize, |
1462 |
uint64_t vidx) |
1463 |
{ |
1464 |
@@ -3496,6 +3542,7 @@ |
1465 |
.fsyncdir = ntfs_fuse_fsync, |
1466 |
.bmap = ntfs_fuse_bmap, |
1467 |
.destroy = ntfs_fuse_destroy2, |
1468 |
+ .ioctl = ntfs_fuse_ioctl, |
1469 |
#if !KERNELPERMS | (POSIXACLS & !KERNELACLS) |
1470 |
.access = ntfs_fuse_access, |
1471 |
#endif |
1472 |
@@ -3512,10 +3559,7 @@ |
1473 |
.setbkuptime = ntfs_macfuse_setbkuptime, |
1474 |
.setchgtime = ntfs_macfuse_setchgtime, |
1475 |
#endif /* defined(__APPLE__) || defined(__DARWIN__) */ |
1476 |
-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \ |
1477 |
- || (defined(__APPLE__) || defined(__DARWIN__)) |
1478 |
.init = ntfs_init |
1479 |
-#endif |
1480 |
}; |
1481 |
|
1482 |
static int ntfs_fuse_init(void) |
1483 |
diff -urN ntfs-3g_ntfsprogs-2014.2.15.old/src/ntfs-3g.c ntfs-3g_ntfsprogs-2014.2.15/src/ntfs-3g.c |
1484 |
--- ntfs-3g_ntfsprogs-2014.2.15.old/src/ntfs-3g.c 2014-02-15 14:07:52.000000000 +0000 |
1485 |
+++ ntfs-3g_ntfsprogs-2014.2.15/src/ntfs-3g.c 2014-07-31 13:51:24.430065816 +0100 |
1486 |
@@ -96,6 +96,7 @@ |
1487 |
#include "logging.h" |
1488 |
#include "xattrs.h" |
1489 |
#include "misc.h" |
1490 |
+#include "ioctl.h" |
1491 |
|
1492 |
#include "ntfs-3g_common.h" |
1493 |
|
1494 |
@@ -636,8 +637,6 @@ |
1495 |
} |
1496 |
#endif /* defined(__APPLE__) || defined(__DARWIN__) */ |
1497 |
|
1498 |
-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \ |
1499 |
- || (defined(__APPLE__) || defined(__DARWIN__)) |
1500 |
static void *ntfs_init(struct fuse_conn_info *conn) |
1501 |
{ |
1502 |
#if defined(__APPLE__) || defined(__DARWIN__) |
1503 |
@@ -653,9 +652,9 @@ |
1504 |
>= SAFE_CAPACITY_FOR_BIG_WRITES)) |
1505 |
conn->want |= FUSE_CAP_BIG_WRITES; |
1506 |
#endif |
1507 |
+ conn->want |= FUSE_CAP_IOCTL_DIR; |
1508 |
return NULL; |
1509 |
} |
1510 |
-#endif /* defined(FUSE_CAP_DONT_MASK) || (defined(__APPLE__) || defined(__DARWIN__)) */ |
1511 |
|
1512 |
static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf) |
1513 |
{ |
1514 |
@@ -2412,6 +2411,28 @@ |
1515 |
return (ret); |
1516 |
} |
1517 |
|
1518 |
+static int ntfs_fuse_ioctl(const char *path, |
1519 |
+ int cmd, void *arg, |
1520 |
+ struct fuse_file_info *fi __attribute__((unused)), |
1521 |
+ unsigned int flags, void *data) |
1522 |
+{ |
1523 |
+ ntfs_inode *ni; |
1524 |
+ int ret; |
1525 |
+ |
1526 |
+ if (flags & FUSE_IOCTL_COMPAT) |
1527 |
+ return -ENOSYS; |
1528 |
+ |
1529 |
+ ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); |
1530 |
+ if (!ni) |
1531 |
+ return -errno; |
1532 |
+ |
1533 |
+ ret = ntfs_ioctl(ni, cmd, arg, flags, data); |
1534 |
+ |
1535 |
+ if (ntfs_inode_close (ni)) |
1536 |
+ set_fuse_error(&ret); |
1537 |
+ return ret; |
1538 |
+} |
1539 |
+ |
1540 |
static int ntfs_fuse_bmap(const char *path, size_t blocksize, uint64_t *idx) |
1541 |
{ |
1542 |
ntfs_inode *ni; |
1543 |
@@ -3335,6 +3356,7 @@ |
1544 |
.fsyncdir = ntfs_fuse_fsync, |
1545 |
.bmap = ntfs_fuse_bmap, |
1546 |
.destroy = ntfs_fuse_destroy2, |
1547 |
+ .ioctl = ntfs_fuse_ioctl, |
1548 |
#if !KERNELPERMS | (POSIXACLS & !KERNELACLS) |
1549 |
.access = ntfs_fuse_access, |
1550 |
.opendir = ntfs_fuse_opendir, |
1551 |
@@ -3352,10 +3374,7 @@ |
1552 |
.setbkuptime = ntfs_macfuse_setbkuptime, |
1553 |
.setchgtime = ntfs_macfuse_setchgtime, |
1554 |
#endif /* defined(__APPLE__) || defined(__DARWIN__) */ |
1555 |
-#if defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_BIG_WRITES) \ |
1556 |
- || (defined(__APPLE__) || defined(__DARWIN__)) |
1557 |
.init = ntfs_init |
1558 |
-#endif |
1559 |
}; |
1560 |
|
1561 |
static int ntfs_fuse_init(void) |