Android-x86
Fork

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-ntfs-3g: コミット

external/ntfs-3g


コミットメタ情報

リビジョン1611b2190866dd6ec736209c86c129f5943bb333 (tree)
日時2017-08-11 16:42:37
作者Jean-Pierre André <jpandre@user...>
コミッターJean-Pierre André

ログメッセージ

Enabled directory operations in plugins

Windows 10 brought a new type of reparse point for directories (0x80000018),
so add opendir() and readdir() to the plugin interface to take directories
into account. The interface for releasedir() is merged with release() as
the plugins can discriminate them if needed.

変更サマリ

差分

--- a/include/ntfs-3g/plugin.h
+++ b/include/ntfs-3g/plugin.h
@@ -30,8 +30,9 @@
3030 #ifndef _NTFS_PLUGIN_H
3131 #define _NTFS_PLUGIN_H
3232
33-#include "inode.h"
3433 #include "layout.h"
34+#include "inode.h"
35+#include "dir.h"
3536
3637 struct fuse_file_info;
3738 struct stat;
@@ -71,10 +72,10 @@ typedef struct plugin_operations {
7172 struct fuse_file_info *fi);
7273
7374 /*
74- * Release an open file
75+ * Release an open file or directory
7576 * This is only called if fi->fh has been set to a non-null
7677 * value while opening. It may be used to free some context
77- * specific to the open file.
78+ * specific to the open file or directory
7879 * The returned value is zero for success or a negative errno
7980 * value for failure.
8081 */
@@ -126,6 +127,30 @@ typedef struct plugin_operations {
126127 */
127128 int (*truncate)(ntfs_inode *ni, const REPARSE_POINT *reparse,
128129 off_t size);
130+ /*
131+ * Open a directory
132+ * The field fi->flags indicates the kind of opening.
133+ * The field fi->fh may be used to store some information which
134+ * will be available to subsequent readdir(). When used
135+ * this field must be non-null and freed in release().
136+ * The returned value is zero for success and a negative errno
137+ * value for failure.
138+ */
139+ int (*opendir)(ntfs_inode *ni, const REPARSE_POINT *reparse,
140+ struct fuse_file_info *fi);
141+
142+ /*
143+ * Get entries from a directory
144+ *
145+ * Use the filldir() function with fillctx argument to return
146+ * the directory entries.
147+ * Names "." and ".." are expected to be returned.
148+ * The returned value is zero for success and a negative errno
149+ * value for failure.
150+ */
151+ int (*readdir)(ntfs_inode *ni, const REPARSE_POINT *reparse,
152+ s64 *pos, void *fillctx, ntfs_filldir_t filldir,
153+ struct fuse_file_info *fi);
129154 } plugin_operations_t;
130155
131156
--- a/src/lowntfs-3g.c
+++ b/src/lowntfs-3g.c
@@ -203,6 +203,9 @@ typedef struct fill_item {
203203 typedef struct fill_context {
204204 struct fill_item *first;
205205 struct fill_item *last;
206+#ifndef DISABLE_PLUGINS
207+ u64 fh;
208+#endif /* DISABLE_PLUGINS */
206209 off_t off;
207210 fuse_req_t req;
208211 fuse_ino_t ino;
@@ -1292,6 +1295,17 @@ static void ntfs_fuse_opendir(fuse_req_t req, fuse_ino_t ino,
12921295 if (!ntfs_allowed_access(&security,ni,accesstype))
12931296 res = -EACCES;
12941297 }
1298+ if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1299+#ifndef DISABLE_PLUGINS
1300+ const plugin_operations_t *ops;
1301+ REPARSE_POINT *reparse;
1302+
1303+ fi->fh = 0;
1304+ res = CALL_REPARSE_PLUGIN(ni, opendir, fi);
1305+#else /* DISABLE_PLUGINS */
1306+ res = -EOPNOTSUPP;
1307+#endif /* DISABLE_PLUGINS */
1308+ }
12951309 if (ntfs_inode_close(ni))
12961310 set_fuse_error(&res);
12971311 if (!res) {
@@ -1305,6 +1319,9 @@ static void ntfs_fuse_opendir(fuse_req_t req, fuse_ino_t ino,
13051319 fill->filled = FALSE;
13061320 fill->ino = ino;
13071321 fill->off = 0;
1322+#ifndef DISABLE_PLUGINS
1323+ fill->fh = fi->fh;
1324+#endif /* DISABLE_PLUGINS */
13081325 }
13091326 fi->fh = (long)fill;
13101327 }
@@ -1321,9 +1338,15 @@ static void ntfs_fuse_releasedir(fuse_req_t req,
13211338 fuse_ino_t ino __attribute__((unused)),
13221339 struct fuse_file_info *fi)
13231340 {
1341+#ifndef DISABLE_PLUGINS
1342+ struct fuse_file_info ufi;
1343+ ntfs_inode *ni;
1344+#endif /* DISABLE_PLUGINS */
13241345 ntfs_fuse_fill_context_t *fill;
13251346 ntfs_fuse_fill_item_t *current;
1347+ int res;
13261348
1349+ res = 0;
13271350 fill = (ntfs_fuse_fill_context_t*)(long)fi->fh;
13281351 if (fill && (fill->ino == ino)) {
13291352 /* make sure to clear results */
@@ -1333,16 +1356,38 @@ static void ntfs_fuse_releasedir(fuse_req_t req,
13331356 free(fill->first);
13341357 fill->first = current;
13351358 }
1359+#ifndef DISABLE_PLUGINS
1360+ if (fill->fh) {
1361+ const plugin_operations_t *ops;
1362+ REPARSE_POINT *reparse;
1363+
1364+ ni = ntfs_inode_open(ctx->vol, INODE(ino));
1365+ if (ni) {
1366+ if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1367+ memcpy(&ufi, fi, sizeof(ufi));
1368+ ufi.fh = fill->fh;
1369+ res = CALL_REPARSE_PLUGIN(ni, release,
1370+ &ufi);
1371+ }
1372+ if (ntfs_inode_close(ni) && !res)
1373+ res = -errno;
1374+ } else
1375+ res = -errno;
1376+ }
1377+#endif /* DISABLE_PLUGINS */
13361378 fill->ino = 0;
13371379 free(fill);
13381380 }
1339- fuse_reply_err(req, 0);
1381+ fuse_reply_err(req, -res);
13401382 }
13411383
13421384 static void ntfs_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
13431385 off_t off __attribute__((unused)),
13441386 struct fuse_file_info *fi __attribute__((unused)))
13451387 {
1388+#ifndef DISABLE_PLUGINS
1389+ struct fuse_file_info ufi;
1390+#endif /* DISABLE_PLUGINS */
13461391 ntfs_fuse_fill_item_t *first;
13471392 ntfs_fuse_fill_item_t *current;
13481393 ntfs_fuse_fill_context_t *fill;
@@ -1379,10 +1424,27 @@ static void ntfs_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
13791424 if (!ni)
13801425 err = -errno;
13811426 else {
1382- if (ntfs_readdir(ni, &pos, fill,
1383- (ntfs_filldir_t)
1427+ if (ni->flags
1428+ & FILE_ATTR_REPARSE_POINT) {
1429+#ifndef DISABLE_PLUGINS
1430+ const plugin_operations_t *ops;
1431+ REPARSE_POINT *reparse;
1432+
1433+ memcpy(&ufi, fi, sizeof(ufi));
1434+ ufi.fh = fill->fh;
1435+ err = CALL_REPARSE_PLUGIN(ni,
1436+ readdir, &pos, fill,
1437+ (ntfs_filldir_t)
1438+ ntfs_fuse_filler, &ufi);
1439+#else /* DISABLE_PLUGINS */
1440+ err = -EOPNOTSUPP;
1441+#endif /* DISABLE_PLUGINS */
1442+ } else {
1443+ if (ntfs_readdir(ni, &pos, fill,
1444+ (ntfs_filldir_t)
13841445 ntfs_fuse_filler))
1385- err = -errno;
1446+ err = -errno;
1447+ }
13861448 fill->filled = TRUE;
13871449 ntfs_fuse_update_times(ni,
13881450 NTFS_UPDATE_ATIME);
--- a/src/ntfs-3g.c
+++ b/src/ntfs-3g.c
@@ -1300,6 +1300,17 @@ static int ntfs_fuse_opendir(const char *path,
13001300 ni,accesstype))
13011301 res = -EACCES;
13021302 }
1303+ if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1304+#ifndef DISABLE_PLUGINS
1305+ const plugin_operations_t *ops;
1306+ REPARSE_POINT *reparse;
1307+
1308+ fi->fh = 0;
1309+ res = CALL_REPARSE_PLUGIN(ni, opendir, fi);
1310+#else /* DISABLE_PLUGINS */
1311+ res = -EOPNOTSUPP;
1312+#endif /* DISABLE_PLUGINS */
1313+ }
13031314 if (ntfs_inode_close(ni))
13041315 set_fuse_error(&res);
13051316 } else
@@ -1323,9 +1334,22 @@ static int ntfs_fuse_readdir(const char *path, void *buf,
13231334 ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
13241335 if (!ni)
13251336 return -errno;
1326- if (ntfs_readdir(ni, &pos, &fill_ctx,
1327- (ntfs_filldir_t)ntfs_fuse_filler))
1328- err = -errno;
1337+
1338+ if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1339+#ifndef DISABLE_PLUGINS
1340+ const plugin_operations_t *ops;
1341+ REPARSE_POINT *reparse;
1342+
1343+ err = CALL_REPARSE_PLUGIN(ni, readdir, &pos, &fill_ctx,
1344+ (ntfs_filldir_t)ntfs_fuse_filler, fi);
1345+#else /* DISABLE_PLUGINS */
1346+ err = -EOPNOTSUPP;
1347+#endif /* DISABLE_PLUGINS */
1348+ } else {
1349+ if (ntfs_readdir(ni, &pos, &fill_ctx,
1350+ (ntfs_filldir_t)ntfs_fuse_filler))
1351+ err = -errno;
1352+ }
13291353 ntfs_fuse_update_times(ni, NTFS_UPDATE_ATIME);
13301354 if (ntfs_inode_close(ni))
13311355 set_fuse_error(&err);
@@ -3732,6 +3756,7 @@ static struct fuse_operations ntfs_3g_ops = {
37323756 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
37333757 .access = ntfs_fuse_access,
37343758 .opendir = ntfs_fuse_opendir,
3759+ .releasedir = ntfs_fuse_release,
37353760 #endif
37363761 #ifdef HAVE_SETXATTR
37373762 .getxattr = ntfs_fuse_getxattr,
旧リポジトリブラウザで表示