From: Hanna Reitz <hreitz@redhat.com>
To: qemu-devel@nongnu.org, virtio-fs@redhat.com
Cc: Hanna Reitz <hreitz@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
Vivek Goyal <vgoyal@redhat.com>
Subject: [PATCH v4 12/12] virtiofsd: Add lazy lo_do_find()
Date: Thu, 16 Sep 2021 10:40:45 +0200 [thread overview]
Message-ID: <20210916084045.31684-13-hreitz@redhat.com> (raw)
In-Reply-To: <20210916084045.31684-1-hreitz@redhat.com>
lo_find() right now takes two lookup keys for two maps, namely the file
handle for inodes_by_handle and the statx information for inodes_by_ids.
However, we only need the statx information if looking up the inode by
the file handle failed.
There are two callers of lo_find(): The first one, lo_do_lookup(), has
both keys anyway, so passing them does not incur any additional cost.
The second one, lookup_name(), though, needs to explicitly invoke
name_to_handle_at() (through get_file_handle()) and statx() (through
do_statx()). We need to try to get a file handle as the primary key, so
we cannot get rid of get_file_handle(), but we only need the statx
information if looking up an inode by handle failed; so we can defer
that until the lookup has indeed failed.
To this end, replace lo_find()'s st/mnt_id parameters by a get_ids()
closure that is invoked to fill the lo_key struct if necessary.
Also, lo_find() is renamed to lo_do_find(), so we can add a new
lo_find() wrapper whose closure just initializes the lo_key from the
st/mnt_id parameters, just like the old lo_find() did.
lookup_name() directly calls lo_do_find() now and passes its own
closure, which performs the do_statx() call.
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
---
tools/virtiofsd/passthrough_ll.c | 93 +++++++++++++++++++++++++-------
1 file changed, 75 insertions(+), 18 deletions(-)
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index e86fad8b2f..368bad17c7 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -1348,22 +1348,23 @@ out_err:
fuse_reply_err(req, saverr);
}
-static struct lo_inode *lo_find(struct lo_data *lo,
- const struct lo_fhandle *fhandle,
- struct stat *st, uint64_t mnt_id)
+/*
+ * get_ids() will be called to get the key for lo->inodes_by_ids if
+ * the lookup by file handle has failed.
+ */
+static struct lo_inode *lo_do_find(struct lo_data *lo,
+ const struct lo_fhandle *fhandle,
+ int (*get_ids)(struct lo_key *, const void *),
+ const void *get_ids_opaque)
{
struct lo_inode *p = NULL;
- struct lo_key ids_key = {
- .ino = st->st_ino,
- .dev = st->st_dev,
- .mnt_id = mnt_id,
- };
+ struct lo_key ids_key;
pthread_mutex_lock(&lo->mutex);
if (fhandle) {
p = g_hash_table_lookup(lo->inodes_by_handle, fhandle);
}
- if (!p) {
+ if (!p && get_ids(&ids_key, get_ids_opaque) == 0) {
p = g_hash_table_lookup(lo->inodes_by_ids, &ids_key);
/*
* When we had to fall back to looking up an inode by its
@@ -1392,6 +1393,36 @@ static struct lo_inode *lo_find(struct lo_data *lo,
return p;
}
+struct lo_find_get_ids_key_opaque {
+ const struct stat *st;
+ uint64_t mnt_id;
+};
+
+static int lo_find_get_ids_key(struct lo_key *ids_key, const void *opaque)
+{
+ const struct lo_find_get_ids_key_opaque *stat_info = opaque;
+
+ *ids_key = (struct lo_key){
+ .ino = stat_info->st->st_ino,
+ .dev = stat_info->st->st_dev,
+ .mnt_id = stat_info->mnt_id,
+ };
+
+ return 0;
+}
+
+static struct lo_inode *lo_find(struct lo_data *lo,
+ const struct lo_fhandle *fhandle,
+ struct stat *st, uint64_t mnt_id)
+{
+ const struct lo_find_get_ids_key_opaque stat_info = {
+ .st = st,
+ .mnt_id = mnt_id,
+ };
+
+ return lo_do_find(lo, fhandle, lo_find_get_ids_key, &stat_info);
+}
+
/* value_destroy_func for posix_locks GHashTable */
static void posix_locks_value_destroy(gpointer data)
{
@@ -1930,14 +1961,41 @@ out:
fuse_reply_err(req, saverr);
}
+struct lookup_name_get_ids_key_opaque {
+ struct lo_data *lo;
+ int parent_fd;
+ const char *name;
+};
+
+static int lookup_name_get_ids_key(struct lo_key *ids_key, const void *opaque)
+{
+ const struct lookup_name_get_ids_key_opaque *stat_params = opaque;
+ uint64_t mnt_id;
+ struct stat attr;
+ int res;
+
+ res = do_statx(stat_params->lo, stat_params->parent_fd, stat_params->name,
+ &attr, AT_SYMLINK_NOFOLLOW, &mnt_id);
+ if (res < 0) {
+ return -errno;
+ }
+
+ *ids_key = (struct lo_key){
+ .ino = attr.st_ino,
+ .dev = attr.st_dev,
+ .mnt_id = mnt_id,
+ };
+
+ return 0;
+}
+
/* Increments nlookup and caller must release refcount using lo_inode_put() */
static struct lo_inode *lookup_name(fuse_req_t req, fuse_ino_t parent,
const char *name)
{
g_auto(TempFd) dir_path_fd = TEMP_FD_INIT;
int res;
- uint64_t mnt_id;
- struct stat attr;
+ struct lookup_name_get_ids_key_opaque stat_params;
struct lo_fhandle *fh;
struct lo_data *lo = lo_data(req);
struct lo_inode *dir = lo_inode(req, parent);
@@ -1955,13 +2013,12 @@ static struct lo_inode *lookup_name(fuse_req_t req, fuse_ino_t parent,
fh = get_file_handle(lo, dir_path_fd.fd, name, NULL);
/* Ignore errors, this is just an optional key for the lookup */
- res = do_statx(lo, dir_path_fd.fd, name, &attr, AT_SYMLINK_NOFOLLOW,
- &mnt_id);
- if (res == -1) {
- goto out;
- }
-
- inode = lo_find(lo, fh, &attr, mnt_id);
+ stat_params = (struct lookup_name_get_ids_key_opaque){
+ .lo = lo,
+ .parent_fd = dir_path_fd.fd,
+ .name = name,
+ };
+ inode = lo_do_find(lo, fh, lookup_name_get_ids_key, &stat_params);
release_file_handle(lo, fh, false);
out:
--
2.31.1
next prev parent reply other threads:[~2021-09-16 8:53 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-16 8:40 [PATCH v4 00/12] virtiofsd: Allow using file handles instead of O_PATH FDs Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 01/12] virtiofsd: Keep /proc/self/mountinfo open Hanna Reitz
2021-10-18 17:07 ` Vivek Goyal
2021-10-20 9:04 ` Hanna Reitz
2021-10-20 18:25 ` Vivek Goyal
2021-09-16 8:40 ` [PATCH v4 02/12] virtiofsd: Limit setxattr()'s creds-dropped region Hanna Reitz
2021-10-18 17:20 ` Vivek Goyal
2021-10-20 9:11 ` Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 03/12] virtiofsd: Add TempFd structure Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 04/12] virtiofsd: Use lo_inode_open() instead of openat() Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 05/12] virtiofsd: Add lo_inode_fd() helper Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 06/12] virtiofsd: Let lo_fd() return a TempFd Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 07/12] virtiofsd: Let lo_inode_open() " Hanna Reitz
2021-10-18 19:18 ` Vivek Goyal
2021-10-20 9:15 ` Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 08/12] virtiofsd: Pass lo_data to lo_inode_{fd,open}() Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 09/12] virtiofsd: Add lo_inode.fhandle Hanna Reitz
2021-09-16 8:40 ` [PATCH v4 10/12] virtiofsd: Add inodes_by_handle hash table Hanna Reitz
2021-10-19 20:02 ` Vivek Goyal
2021-10-20 10:02 ` Hanna Reitz
2021-10-20 12:29 ` Vivek Goyal
2021-10-20 14:10 ` Hanna Reitz
2021-10-20 18:06 ` Vivek Goyal
2021-10-20 12:53 ` Vivek Goyal
2021-09-16 8:40 ` [PATCH v4 11/12] virtiofsd: Optionally fill lo_inode.fhandle Hanna Reitz
2021-10-19 18:57 ` Vivek Goyal
2021-10-20 10:00 ` Hanna Reitz
2021-10-20 18:53 ` Vivek Goyal
2021-09-16 8:40 ` Hanna Reitz [this message]
2021-10-18 18:08 ` [PATCH v4 00/12] virtiofsd: Allow using file handles instead of O_PATH FDs Vivek Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210916084045.31684-13-hreitz@redhat.com \
--to=hreitz@redhat.com \
--cc=dgilbert@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=vgoyal@redhat.com \
--cc=virtio-fs@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).