From: Greg Kurz <groug@kaod.org>
To: antonios.motakis@huawei.com
Cc: qemu-devel@nongnu.org, veaceslav.falico@huawei.com,
Eduard.Shishkin@huawei.com, andy.wangguoli@huawei.com,
Jani.Kokkonen@huawei.com, cota@braap.org, berrange@redhat.com
Subject: Re: [Qemu-devel] [PATCH 4/4] 9pfs: stat_to_qid: implement slow path
Date: Fri, 9 Feb 2018 16:22:33 +0100 [thread overview]
Message-ID: <20180209162233.1d191ace@bahia.lan> (raw)
In-Reply-To: <20180208180019.13683-5-antonios.motakis@huawei.com>
On Thu, 8 Feb 2018 19:00:19 +0100
<antonios.motakis@huawei.com> wrote:
> From: Antonios Motakis <antonios.motakis@huawei.com>
>
> stat_to_qid attempts via qid_path_prefixmap to map unique files
> (which are identified by 64bt inode nr and 32 bit device id)
> to a 64 QID path value. However this implementation makes some
> assumptions about inode number generation on the host.
>
> If qid_path_prefixmap fails, we still have 48bits available in
> the QID path to fall back to a less memory efficient full mapping.
>
> Signed-off-by: Antonios Motakis <antonios.motakis@huawei.com>
> ---
> hw/9pfs/9p.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
> hw/9pfs/9p.h | 9 +++++++++
> 2 files changed, 70 insertions(+), 5 deletions(-)
>
> diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
> index f434f05..ae7845d 100644
> --- a/hw/9pfs/9p.c
> +++ b/hw/9pfs/9p.c
> @@ -581,23 +581,72 @@ static uint32_t qpp_hash(QppEntry e)
> return tb_hash_func7(e.ino_prefix, e.dev, 0, 0, 0);
> }
>
> +static uint32_t qpf_hash(QpfEntry e)
> +{
> + return tb_hash_func7(e.ino, e.dev, 0, 0, 0);
Same remark as with previous patch, obviously :)
> +}
> +
> static bool qpp_lookup_func(const void *obj, const void *userp)
> {
> const QppEntry *e1 = obj, *e2 = userp;
> return (e1->dev == e2->dev) && (e1->ino_prefix == e2->ino_prefix);
Parenthesitis ? ;)
> }
>
> -static void qpp_table_remove(struct qht *ht, void *p, uint32_t h, void *up)
> +static bool qpf_lookup_func(const void *obj, const void *userp)
> +{
> + const QpfEntry *e1 = obj, *e2 = userp;
> + return (e1->dev == e2->dev) && (e1->ino == e2->ino);
Parenthesitis ? ;)
> +}
> +
> +static void qp_table_remove(struct qht *ht, void *p, uint32_t h, void *up)
> {
> g_free(p);
> }
>
> -static void qpp_table_destroy(struct qht *ht)
> +static void qp_table_destroy(struct qht *ht)
> {
> - qht_iter(ht, qpp_table_remove, NULL);
> + qht_iter(ht, qp_table_remove, NULL);
> qht_destroy(ht);
> }
>
> +static int qid_path_fullmap(V9fsPDU *pdu, const struct stat *stbuf,
> + uint64_t *path)
> +{
> + QpfEntry lookup = {
> + .dev = stbuf->st_dev,
> + .ino = stbuf->st_ino
> + }, *val;
> + uint32_t hash = qpf_hash(lookup);
> +
> + /* most users won't need the fullmap, so init the table lazily */
> + if (!pdu->s->qpf_table.map) {
> + qht_init(&pdu->s->qpf_table, 1 << 16, QHT_MODE_AUTO_RESIZE);
> + }
> +
> + val = qht_lookup(&pdu->s->qpf_table, qpf_lookup_func, &lookup, hash);
> +
> + if (!val) {
> + if (pdu->s->qp_fullpath_next == 0) {
> + /* no more files can be mapped :'( */
> + return -ENFILE;
> + }
> +
> + val = g_malloc0(sizeof(QppEntry));
> + if (!val) {
> + return -ENOMEM;
> + }
> + *val = lookup;
> +
> + /* new unique inode and device combo */
> + val->path = pdu->s->qp_fullpath_next++;
> + pdu->s->qp_fullpath_next &= QPATH_INO_MASK;
> + qht_insert(&pdu->s->qpf_table, val, hash);
> + }
> +
> + *path = val->path;
> + return 0;
> +}
> +
> /* stat_to_qid needs to map inode number (64 bits) and device id (32 bits)
> * to a unique QID path (64 bits). To avoid having to map and keep track
> * of up to 2^64 objects, we map only the 16 highest bits of the inode plus
> @@ -646,6 +695,10 @@ static int stat_to_qid(V9fsPDU *pdu, const struct stat *stbuf, V9fsQID *qidp)
>
> /* map inode+device to qid path (fast path) */
> err = qid_path_prefixmap(pdu, stbuf, &qidp->path);
> + if (err == -ENFILE) {
> + /* fast path didn't work, fal back to full map */
> + err = qid_path_fullmap(pdu, stbuf, &qidp->path);
Hmm... if we have already generate QIDs with fast path, how
can we be sure we won't collide with the ones from the full
map ?
IIRC, Emilio had suggested to use bit 63 to distinguish between
fast and slow path.
> + }
> if (err) {
> return err;
> }
> @@ -3693,6 +3746,7 @@ int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t,
> /* QID path hash table. 1 entry ought to be enough for anybody ;) */
> qht_init(&s->qpp_table, 1, QHT_MODE_AUTO_RESIZE);
> s->qp_prefix_next = 1; /* reserve 0 to detect overflow */
> + s->qp_fullpath_next = 1;
>
> s->ctx.fst = &fse->fst;
> fsdev_throttle_init(s->ctx.fst);
> @@ -3707,7 +3761,8 @@ out:
> }
> g_free(s->tag);
> g_free(s->ctx.fs_root);
> - qpp_table_destroy(&s->qpp_table);
> + qp_table_destroy(&s->qpp_table);
> + qp_table_destroy(&s->qpf_table);
> v9fs_path_free(&path);
> }
> return rc;
> @@ -3720,7 +3775,8 @@ void v9fs_device_unrealize_common(V9fsState *s, Error **errp)
> }
> fsdev_throttle_cleanup(s->ctx.fst);
> g_free(s->tag);
> - qpp_table_destroy(&s->qpp_table);
> + qp_table_destroy(&s->qpp_table);
> + qp_table_destroy(&s->qpf_table);
> g_free(s->ctx.fs_root);
> }
>
> diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
> index 80428f7..b561f4a 100644
> --- a/hw/9pfs/9p.h
> +++ b/hw/9pfs/9p.h
> @@ -241,6 +241,13 @@ typedef struct {
> uint16_t qp_prefix;
> } QppEntry;
>
> +/* QID path full entry, as above */
> +typedef struct {
> + dev_t dev;
> + ino_t ino;
> + uint64_t path;
> +} QpfEntry;
> +
> struct V9fsState
> {
> QLIST_HEAD(, V9fsPDU) free_list;
> @@ -263,7 +270,9 @@ struct V9fsState
> V9fsConf fsconf;
> V9fsQID root_qid;
> struct qht qpp_table;
> + struct qht qpf_table;
> uint16_t qp_prefix_next;
> + uint64_t qp_fullpath_next;
> };
>
> /* 9p2000.L open flags */
next prev parent reply other threads:[~2018-02-09 15:24 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-08 18:00 [Qemu-devel] [PATCH 0/4] QID path collision fix antonios.motakis
2018-02-08 18:00 ` [Qemu-devel] [PATCH 1/4] 9pfs: V9fsQID: set type of version and path to unsigned antonios.motakis
2018-02-09 12:37 ` Greg Kurz
2018-02-16 10:19 ` Antonios Motakis
2018-02-08 18:00 ` [Qemu-devel] [PATCH 2/4] 9pfs: check for file device to avoid QID path collisions antonios.motakis
2018-02-09 13:03 ` Greg Kurz
2018-02-16 10:19 ` Antonios Motakis
2018-02-08 18:00 ` [Qemu-devel] [PATCH 3/4] 9pfs: stat_to_qid: use device as input to qid.path antonios.motakis
2018-02-09 15:13 ` Greg Kurz
2018-02-09 16:06 ` Eric Blake
2018-02-09 17:57 ` Greg Kurz
2018-02-16 10:20 ` Antonios Motakis
2018-02-16 11:21 ` Greg Kurz
2018-02-09 21:58 ` Emilio G. Cota
2018-02-16 10:19 ` Antonios Motakis
2018-02-08 18:00 ` [Qemu-devel] [PATCH 4/4] 9pfs: stat_to_qid: implement slow path antonios.motakis
2018-02-09 15:22 ` Greg Kurz [this message]
2018-02-09 21:47 ` Emilio G. Cota
2018-02-16 10:28 ` Antonios Motakis
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=20180209162233.1d191ace@bahia.lan \
--to=groug@kaod.org \
--cc=Eduard.Shishkin@huawei.com \
--cc=Jani.Kokkonen@huawei.com \
--cc=andy.wangguoli@huawei.com \
--cc=antonios.motakis@huawei.com \
--cc=berrange@redhat.com \
--cc=cota@braap.org \
--cc=qemu-devel@nongnu.org \
--cc=veaceslav.falico@huawei.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 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.