Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DAOS-14733: Add FUSE_PARALLEL_DIROPS patch #3

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
From 4df08719f3415cde6f802a755922b7f76e198cd7 Mon Sep 17 00:00:00 2001
From: Dharmendra Singh <[email protected]>
Date: Mon, 28 Feb 2022 11:15:06 +0000
Subject: [PATCH] Modify structures in libfuse to handle flags beyond 32 bits.

In fuse kernel, 'commit 53db28933e95 ("fuse: extend init flags")'
made the changes to handle flags going beyond 32 bits but i think
changes were not done in libfuse to handle the same.

This patch prepares the ground in libfuse for incoming FUSE kernel
patches (Atomic open + lookup) where flags went beyond 32 bits.
It makes struct same as in fuse kernel resulting in name change of
few fields.
---
include/fuse_kernel.h | 8 ++++-
lib/fuse_lowlevel.c | 75 ++++++++++++++++++++++++++++----------------------
2 files changed, 48 insertions(+), 35 deletions(-)

--- a/include/fuse_kernel.h
+++ b/include/fuse_kernel.h
@@ -272,6 +272,7 @@ struct fuse_file_lock {
#define FUSE_POSIX_ACL (1 << 20)
#define FUSE_MAX_PAGES (1 << 22)
#define FUSE_CACHE_SYMLINKS (1 << 23)
+#define FUSE_INIT_EXT (1 << 30)

/**
* CUSE INIT request/reply flags
@@ -596,6 +597,8 @@ struct fuse_init_in {
uint32_t minor;
uint32_t max_readahead;
uint32_t flags;
+ uint32_t flags2;
+ uint32_t unused[11];
};

#define FUSE_COMPAT_INIT_OUT_SIZE 8
@@ -611,8 +614,9 @@ struct fuse_init_out {
uint32_t max_write;
uint32_t time_gran;
uint16_t max_pages;
- uint16_t padding;
- uint32_t unused[8];
+ uint16_t map_alignment;
+ uint32_t flags2;
+ uint32_t unused[7];
};

#define CUSE_INIT_INFO_MAX 4096
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -1819,7 +1819,8 @@ static void do_init(fuse_req_t req, fuse
struct fuse_session *se = req->se;
size_t bufsize = se->bufsize;
size_t outargsize = sizeof(outarg);
-
+ uint64_t inargflags = 0;
+ uint64_t outargflags = 0;
(void) nodeid;
if (se->debug) {
fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor);
@@ -1854,39 +1855,42 @@ static void do_init(fuse_req_t req, fuse
if (arg->minor >= 6) {
if (arg->max_readahead < se->conn.max_readahead)
se->conn.max_readahead = arg->max_readahead;
- if (arg->flags & FUSE_ASYNC_READ)
+ inargflags = arg->flags;
+ if (inargflags & FUSE_INIT_EXT)
+ inargflags = inargflags | (uint64_t) arg->flags2 << 32;
+ if (inargflags & FUSE_ASYNC_READ)
se->conn.capable |= FUSE_CAP_ASYNC_READ;
- if (arg->flags & FUSE_POSIX_LOCKS)
+ if (inargflags & FUSE_POSIX_LOCKS)
se->conn.capable |= FUSE_CAP_POSIX_LOCKS;
- if (arg->flags & FUSE_ATOMIC_O_TRUNC)
+ if (inargflags & FUSE_ATOMIC_O_TRUNC)
se->conn.capable |= FUSE_CAP_ATOMIC_O_TRUNC;
- if (arg->flags & FUSE_EXPORT_SUPPORT)
+ if (inargflags & FUSE_EXPORT_SUPPORT)
se->conn.capable |= FUSE_CAP_EXPORT_SUPPORT;
- if (arg->flags & FUSE_DONT_MASK)
+ if (inargflags & FUSE_DONT_MASK)
se->conn.capable |= FUSE_CAP_DONT_MASK;
- if (arg->flags & FUSE_FLOCK_LOCKS)
+ if (inargflags & FUSE_FLOCK_LOCKS)
se->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
- if (arg->flags & FUSE_AUTO_INVAL_DATA)
+ if (inargflags & FUSE_AUTO_INVAL_DATA)
se->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA;
- if (arg->flags & FUSE_DO_READDIRPLUS)
+ if (inargflags & FUSE_DO_READDIRPLUS)
se->conn.capable |= FUSE_CAP_READDIRPLUS;
- if (arg->flags & FUSE_READDIRPLUS_AUTO)
+ if (inargflags & FUSE_READDIRPLUS_AUTO)
se->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO;
- if (arg->flags & FUSE_ASYNC_DIO)
+ if (inargflags & FUSE_ASYNC_DIO)
se->conn.capable |= FUSE_CAP_ASYNC_DIO;
- if (arg->flags & FUSE_WRITEBACK_CACHE)
+ if (inargflags & FUSE_WRITEBACK_CACHE)
se->conn.capable |= FUSE_CAP_WRITEBACK_CACHE;
- if (arg->flags & FUSE_NO_OPEN_SUPPORT)
+ if (inargflags & FUSE_NO_OPEN_SUPPORT)
se->conn.capable |= FUSE_CAP_NO_OPEN_SUPPORT;
- if (arg->flags & FUSE_PARALLEL_DIROPS)
+ if (inargflags & FUSE_PARALLEL_DIROPS)
se->conn.capable |= FUSE_CAP_PARALLEL_DIROPS;
- if (arg->flags & FUSE_POSIX_ACL)
+ if (inargflags & FUSE_POSIX_ACL)
se->conn.capable |= FUSE_CAP_POSIX_ACL;
- if (arg->flags & FUSE_HANDLE_KILLPRIV)
+ if (inargflags & FUSE_HANDLE_KILLPRIV)
se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
- if (arg->flags & FUSE_CACHE_SYMLINKS)
+ if (inargflags & FUSE_CACHE_SYMLINKS)
se->conn.capable |= FUSE_CAP_CACHE_SYMLINKS;
- if (!(arg->flags & FUSE_MAX_PAGES)) {
+ if (!(inargflags & FUSE_MAX_PAGES)) {
size_t max_bufsize =
FUSE_DEFAULT_MAX_PAGES_PER_REQ * getpagesize()
+ FUSE_BUFFER_HEADER_SIZE;
@@ -1977,37 +1981,42 @@ static void do_init(fuse_req_t req, fuse
outarg.flags |= FUSE_MAX_PAGES;
outarg.max_pages = (se->conn.max_write - 1) / getpagesize() + 1;
}
-
+ outargflags = outarg.flags;
/* Always enable big writes, this is superseded
by the max_write option */
- outarg.flags |= FUSE_BIG_WRITES;
+ outargflags |= FUSE_BIG_WRITES;

if (se->conn.want & FUSE_CAP_ASYNC_READ)
- outarg.flags |= FUSE_ASYNC_READ;
+ outargflags |= FUSE_ASYNC_READ;
if (se->conn.want & FUSE_CAP_POSIX_LOCKS)
- outarg.flags |= FUSE_POSIX_LOCKS;
+ outargflags |= FUSE_POSIX_LOCKS;
if (se->conn.want & FUSE_CAP_ATOMIC_O_TRUNC)
- outarg.flags |= FUSE_ATOMIC_O_TRUNC;
+ outargflags |= FUSE_ATOMIC_O_TRUNC;
if (se->conn.want & FUSE_CAP_EXPORT_SUPPORT)
- outarg.flags |= FUSE_EXPORT_SUPPORT;
+ outargflags |= FUSE_EXPORT_SUPPORT;
if (se->conn.want & FUSE_CAP_DONT_MASK)
- outarg.flags |= FUSE_DONT_MASK;
+ outargflags |= FUSE_DONT_MASK;
if (se->conn.want & FUSE_CAP_FLOCK_LOCKS)
- outarg.flags |= FUSE_FLOCK_LOCKS;
+ outargflags |= FUSE_FLOCK_LOCKS;
if (se->conn.want & FUSE_CAP_AUTO_INVAL_DATA)
- outarg.flags |= FUSE_AUTO_INVAL_DATA;
+ outargflags |= FUSE_AUTO_INVAL_DATA;
if (se->conn.want & FUSE_CAP_READDIRPLUS)
- outarg.flags |= FUSE_DO_READDIRPLUS;
+ outargflags |= FUSE_DO_READDIRPLUS;
if (se->conn.want & FUSE_CAP_READDIRPLUS_AUTO)
- outarg.flags |= FUSE_READDIRPLUS_AUTO;
+ outargflags |= FUSE_READDIRPLUS_AUTO;
if (se->conn.want & FUSE_CAP_ASYNC_DIO)
- outarg.flags |= FUSE_ASYNC_DIO;
+ outargflags |= FUSE_ASYNC_DIO;
if (se->conn.want & FUSE_CAP_WRITEBACK_CACHE)
- outarg.flags |= FUSE_WRITEBACK_CACHE;
+ outargflags |= FUSE_WRITEBACK_CACHE;
if (se->conn.want & FUSE_CAP_POSIX_ACL)
- outarg.flags |= FUSE_POSIX_ACL;
+ outargflags |= FUSE_POSIX_ACL;
if (se->conn.want & FUSE_CAP_CACHE_SYMLINKS)
- outarg.flags |= FUSE_CACHE_SYMLINKS;
+ outargflags |= FUSE_CACHE_SYMLINKS;
+
+ outarg.flags = outargflags;
+
+ if (inargflags & FUSE_INIT_EXT)
+ outarg.flags2 = outargflags >> 32;
outarg.max_readahead = se->conn.max_readahead;
outarg.max_write = se->conn.max_write;
if (se->conn.proto_minor >= 13) {
118 changes: 118 additions & 0 deletions 0006-BZ_2171095.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
From 22cc0c761ad23395a8220ce1954cfb8a64f36ff4 Mon Sep 17 00:00:00 2001
From: HereThereBeDragons <[email protected]>
Date: Thu, 27 Oct 2022 17:52:10 +0200
Subject: [PATCH] Initial patch provided by Miklos Szeredi
<[email protected]>

---
include/fuse_kernel.h | 8 +++++++-
include/fuse_lowlevel.h | 8 ++++++++
lib/fuse_lowlevel.c | 18 ++++++++++++++----
lib/fuse_versionscript | 1 +
4 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h
index 09da620b5..e0666a1f7 100644
--- a/include/fuse_kernel.h
+++ b/include/fuse_kernel.h
@@ -336,6 +336,12 @@
*/
#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)

+/**
+ * notify_inval_entry flags
+ * FUSE_EXPIRE_ONLY
+ */
+#define FUSE_EXPIRE_ONLY (1 << 0)
+
enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */
@@ -800,7 +806,7 @@ struct fuse_notify_inval_inode_out {
struct fuse_notify_inval_entry_out {
uint64_t parent;
uint32_t namelen;
- uint32_t padding;
+ uint32_t flags;
};

struct fuse_notify_delete_out {
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 53f0fcf4b..c955cc4bb 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -1675,6 +1675,14 @@ int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino,
int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
const char *name, size_t namelen);

+enum fuse_expire_flags {
+ FUSE_LL_EXPIRE_ONLY = (1 << 0),
+};
+
+int fuse_lowlevel_notify_expire_entry(struct fuse_session *se, fuse_ino_t parent,
+ const char *name, size_t namelen,
+ enum fuse_expire_flags flags);
+
/**
* This function behaves like fuse_lowlevel_notify_inval_entry() with
* the following additional effect (at least as of Linux kernel 4.8):
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index e82cd9e9f..7b9d71043 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -2161,21 +2161,24 @@
return send_notify_iov(se, FUSE_NOTIFY_INVAL_INODE, iov, 2);
}

-int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
- const char *name, size_t namelen)
+int fuse_lowlevel_notify_expire_entry(struct fuse_session *se, fuse_ino_t parent,
+ const char *name, size_t namelen,
+ enum fuse_expire_flags flags)
{
struct fuse_notify_inval_entry_out outarg;
struct iovec iov[3];

if (!se)
return -EINVAL;
-
+
if (se->conn.proto_major < 6 || se->conn.proto_minor < 12)
return -ENOSYS;

outarg.parent = parent;
outarg.namelen = namelen;
- outarg.padding = 0;
+ outarg.flags = 0;
+ if (flags & FUSE_LL_EXPIRE_ONLY)
+ outarg.flags |= FUSE_EXPIRE_ONLY;

iov[1].iov_base = &outarg;
iov[1].iov_len = sizeof(outarg);
@@ -2292,6 +2295,13 @@ int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
return send_notify_iov(se, FUSE_NOTIFY_INVAL_ENTRY, iov, 3);
}

+int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
+ const char *name, size_t namelen)
+{
+ return fuse_lowlevel_notify_expire_entry(se, parent, name, namelen, 0);
+}
+
+
int fuse_lowlevel_notify_delete(struct fuse_session *se,
fuse_ino_t parent, fuse_ino_t child,
const char *name, size_t namelen)
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index 7e50e7507..795ea4aa9 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -151,6 +151,7 @@
FUSE_3.3 {
global:
fuse_open_channel;
+ fuse_lowlevel_notify_expire_entr;
} FUSE_3.2;

# Local Variables:

Loading