From: Max Reitz <mreitz@redhat.com> To: qemu-devel@nongnu.org, virtio-fs@redhat.com Cc: "Dr . David Alan Gilbert" <dgilbert@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>, Max Reitz <mreitz@redhat.com> Subject: [PATCH v2 9/9] virtiofsd: Add lazy lo_do_find() Date: Wed, 9 Jun 2021 17:55:51 +0200 [thread overview] Message-ID: <20210609155551.44437-10-mreitz@redhat.com> (raw) In-Reply-To: <20210609155551.44437-1-mreitz@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: Max Reitz <mreitz@redhat.com> Reviewed-by: Connor Kuehl <ckuehl@redhat.com> --- tools/virtiofsd/passthrough_ll.c | 93 ++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 17 deletions(-) diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c index 2e56c40b2f..8990fd5bd2 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -1168,22 +1168,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 IDs, @@ -1211,6 +1212,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) { @@ -1682,14 +1713,41 @@ out_err: 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_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); @@ -1707,13 +1765,14 @@ static struct lo_inode *lookup_name(fuse_req_t req, fuse_ino_t parent, fh = get_file_handle(lo, dir_fd.fd, name); /* Ignore errors, this is just an optional key for the lookup */ - res = do_statx(lo, dir_fd.fd, name, &attr, AT_SYMLINK_NOFOLLOW, &mnt_id); - lo_inode_put(lo, &dir); - if (res == -1) { - return NULL; - } + stat_params = (struct lookup_name_get_ids_key_opaque){ + .lo = lo, + .parent_fd = dir_fd.fd, + .name = name, + }; - inode = lo_find(lo, fh, &attr, mnt_id); + inode = lo_do_find(lo, fh, lookup_name_get_ids_key, &stat_params); + lo_inode_put(lo, &dir); g_free(fh); return inode; -- 2.31.1
WARNING: multiple messages have this Message-ID (diff)
From: Max Reitz <mreitz@redhat.com> To: qemu-devel@nongnu.org, virtio-fs@redhat.com Cc: Max Reitz <mreitz@redhat.com> Subject: [Virtio-fs] [PATCH v2 9/9] virtiofsd: Add lazy lo_do_find() Date: Wed, 9 Jun 2021 17:55:51 +0200 [thread overview] Message-ID: <20210609155551.44437-10-mreitz@redhat.com> (raw) In-Reply-To: <20210609155551.44437-1-mreitz@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: Max Reitz <mreitz@redhat.com> Reviewed-by: Connor Kuehl <ckuehl@redhat.com> --- tools/virtiofsd/passthrough_ll.c | 93 ++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 17 deletions(-) diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c index 2e56c40b2f..8990fd5bd2 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -1168,22 +1168,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 IDs, @@ -1211,6 +1212,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) { @@ -1682,14 +1713,41 @@ out_err: 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_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); @@ -1707,13 +1765,14 @@ static struct lo_inode *lookup_name(fuse_req_t req, fuse_ino_t parent, fh = get_file_handle(lo, dir_fd.fd, name); /* Ignore errors, this is just an optional key for the lookup */ - res = do_statx(lo, dir_fd.fd, name, &attr, AT_SYMLINK_NOFOLLOW, &mnt_id); - lo_inode_put(lo, &dir); - if (res == -1) { - return NULL; - } + stat_params = (struct lookup_name_get_ids_key_opaque){ + .lo = lo, + .parent_fd = dir_fd.fd, + .name = name, + }; - inode = lo_find(lo, fh, &attr, mnt_id); + inode = lo_do_find(lo, fh, lookup_name_get_ids_key, &stat_params); + lo_inode_put(lo, &dir); g_free(fh); return inode; -- 2.31.1
next prev parent reply other threads:[~2021-06-09 16:11 UTC|newest] Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-06-09 15:55 [PATCH v2 0/9] virtiofsd: Allow using file handles instead of O_PATH FDs Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 1/9] virtiofsd: Add TempFd structure Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 2/9] virtiofsd: Use lo_inode_open() instead of openat() Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 3/9] virtiofsd: Add lo_inode_fd() helper Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 4/9] virtiofsd: Let lo_fd() return a TempFd Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 5/9] virtiofsd: Let lo_inode_open() " Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 6/9] virtiofsd: Add lo_inode.fhandle Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 7/9] virtiofsd: Add inodes_by_handle hash table Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-11 20:04 ` Vivek Goyal 2021-06-16 13:38 ` Max Reitz 2021-06-17 21:21 ` Vivek Goyal 2021-06-18 8:28 ` Max Reitz 2021-06-18 18:29 ` Vivek Goyal 2021-06-21 9:02 ` Max Reitz 2021-06-21 15:51 ` Vivek Goyal 2021-06-21 17:07 ` Max Reitz 2021-06-21 21:27 ` Vivek Goyal 2021-07-13 15:07 ` Max Reitz 2021-07-20 14:50 ` Vivek Goyal 2021-07-21 8:29 ` Max Reitz 2021-06-18 8:30 ` Max Reitz 2021-06-18 8:30 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` [PATCH v2 8/9] virtiofsd: Optionally fill lo_inode.fhandle Max Reitz 2021-06-09 15:55 ` [Virtio-fs] " Max Reitz 2021-06-09 15:55 ` Max Reitz [this message] 2021-06-09 15:55 ` [Virtio-fs] [PATCH v2 9/9] virtiofsd: Add lazy lo_do_find() Max Reitz 2021-06-11 19:19 ` [PATCH v2 0/9] virtiofsd: Allow using file handles instead of O_PATH FDs Vivek Goyal 2021-06-11 19:19 ` [Virtio-fs] " Vivek Goyal 2021-06-16 13:41 ` Max Reitz 2021-06-16 13:41 ` [Virtio-fs] " Max Reitz
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=20210609155551.44437-10-mreitz@redhat.com \ --to=mreitz@redhat.com \ --cc=dgilbert@redhat.com \ --cc=qemu-devel@nongnu.org \ --cc=stefanha@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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.