From nobody Wed May 1 00:34:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151811627383052.1516627045346; Thu, 8 Feb 2018 10:57:53 -0800 (PST) Received: from localhost ([::1]:36236 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejrOI-0003t1-TI for importer@patchew.org; Thu, 08 Feb 2018 13:57:50 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35514) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejqTz-0002S6-73 for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ejqTw-0006sO-6B for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:39 -0500 Received: from lhrrgout.huawei.com ([194.213.3.17]:43312 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ejqTv-0006r5-Vm for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:36 -0500 Received: from lhreml704-cah.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id 7FBE56297AD5F; Thu, 8 Feb 2018 17:59:30 +0000 (GMT) Received: from localhost.localdomain (10.204.62.86) by lhreml704-cah.china.huawei.com (10.201.108.45) with Microsoft SMTP Server id 14.3.361.1; Thu, 8 Feb 2018 17:59:22 +0000 From: To: , Date: Thu, 8 Feb 2018 19:00:16 +0100 Message-ID: <20180208180019.13683-2-antonios.motakis@huawei.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180208180019.13683-1-antonios.motakis@huawei.com> References: <20180208180019.13683-1-antonios.motakis@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.62.86] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 194.213.3.17 Subject: [Qemu-devel] [PATCH 1/4] 9pfs: V9fsQID: set type of version and path to unsigned X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: veaceslav.falico@huawei.com, Eduard.Shishkin@huawei.com, andy.wangguoli@huawei.com, cota@braap.org, Antonios Motakis , Jani.Kokkonen@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Antonios Motakis There is no need for signedness on these QID fields for 9p. Signed-off-by: Antonios Motakis --- fsdev/9p-marshal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fsdev/9p-marshal.h b/fsdev/9p-marshal.h index c8823d8..d1ad364 100644 --- a/fsdev/9p-marshal.h +++ b/fsdev/9p-marshal.h @@ -10,8 +10,8 @@ typedef struct V9fsString typedef struct V9fsQID { int8_t type; - int32_t version; - int64_t path; + uint32_t version; + uint64_t path; } V9fsQID; =20 typedef struct V9fsStat --=20 1.8.3.1 From nobody Wed May 1 00:34:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1518116422317478.77990914146983; Thu, 8 Feb 2018 11:00:22 -0800 (PST) Received: from localhost ([::1]:36506 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejrQj-0006Ge-FA for importer@patchew.org; Thu, 08 Feb 2018 14:00:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35512) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejqTz-0002S4-72 for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ejqTw-0006sl-AZ for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:39 -0500 Received: from lhrrgout.huawei.com ([194.213.3.17]:43311 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ejqTv-0006r3-Vm for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:36 -0500 Received: from lhreml704-cah.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id 6FEE7513ECA13; Thu, 8 Feb 2018 17:59:30 +0000 (GMT) Received: from localhost.localdomain (10.204.62.86) by lhreml704-cah.china.huawei.com (10.201.108.45) with Microsoft SMTP Server id 14.3.361.1; Thu, 8 Feb 2018 17:59:23 +0000 From: To: , Date: Thu, 8 Feb 2018 19:00:17 +0100 Message-ID: <20180208180019.13683-3-antonios.motakis@huawei.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180208180019.13683-1-antonios.motakis@huawei.com> References: <20180208180019.13683-1-antonios.motakis@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.62.86] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 194.213.3.17 Subject: [Qemu-devel] [PATCH 2/4] 9pfs: check for file device to avoid QID path collisions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: veaceslav.falico@huawei.com, Eduard.Shishkin@huawei.com, andy.wangguoli@huawei.com, cota@braap.org, Antonios Motakis , Jani.Kokkonen@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Antonios Motakis The QID path should uniquely identify a file. However, the inode of a file is currently used as the QID path, which on its own only uniquely identifies wiles within a device. Here we track the device hosting the 9pfs share, in order to prevent security issues with QID path collisions from other devices. Signed-off-by: Antonios Motakis --- hw/9pfs/9p.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++---------= ---- hw/9pfs/9p.h | 1 + 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 85a1ed8..4da858f 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -573,10 +573,16 @@ static void coroutine_fn virtfs_reset(V9fsPDU *pdu) P9_STAT_MODE_SOCKET) =20 /* This is the algorithm from ufs in spfs */ -static void stat_to_qid(const struct stat *stbuf, V9fsQID *qidp) +static int stat_to_qid(V9fsPDU *pdu, const struct stat *stbuf, V9fsQID *qi= dp) { size_t size; =20 + if (pdu->s->dev_id =3D=3D 0) { + pdu->s->dev_id =3D stbuf->st_dev; + } else if (pdu->s->dev_id !=3D stbuf->st_dev) { + return -ENOSYS; + } + memset(&qidp->path, 0, sizeof(qidp->path)); size =3D MIN(sizeof(stbuf->st_ino), sizeof(qidp->path)); memcpy(&qidp->path, &stbuf->st_ino, size); @@ -588,6 +594,8 @@ static void stat_to_qid(const struct stat *stbuf, V9fsQ= ID *qidp) if (S_ISLNK(stbuf->st_mode)) { qidp->type |=3D P9_QID_TYPE_SYMLINK; } + + return 0; } =20 static int coroutine_fn fid_to_qid(V9fsPDU *pdu, V9fsFidState *fidp, @@ -600,7 +608,10 @@ static int coroutine_fn fid_to_qid(V9fsPDU *pdu, V9fsF= idState *fidp, if (err < 0) { return err; } - stat_to_qid(&stbuf, qidp); + err =3D stat_to_qid(pdu, &stbuf, qidp); + if (err < 0) { + return err; + } return 0; } =20 @@ -831,7 +842,10 @@ static int coroutine_fn stat_to_v9stat(V9fsPDU *pdu, V= 9fsPath *path, =20 memset(v9stat, 0, sizeof(*v9stat)); =20 - stat_to_qid(stbuf, &v9stat->qid); + err =3D stat_to_qid(pdu, stbuf, &v9stat->qid); + if (err < 0) { + return err; + } v9stat->mode =3D stat_to_v9mode(stbuf); v9stat->atime =3D stbuf->st_atime; v9stat->mtime =3D stbuf->st_mtime; @@ -892,7 +906,7 @@ static int coroutine_fn stat_to_v9stat(V9fsPDU *pdu, V9= fsPath *path, #define P9_STATS_ALL 0x00003fffULL /* Mask for All fields above = */ =20 =20 -static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf, +static int stat_to_v9stat_dotl(V9fsPDU *pdu, const struct stat *stbuf, V9fsStatDotl *v9lstat) { memset(v9lstat, 0, sizeof(*v9lstat)); @@ -914,7 +928,7 @@ static void stat_to_v9stat_dotl(V9fsState *s, const str= uct stat *stbuf, /* Currently we only support BASIC fields in stat */ v9lstat->st_result_mask =3D P9_STATS_BASIC; =20 - stat_to_qid(stbuf, &v9lstat->qid); + return stat_to_qid(pdu, stbuf, &v9lstat->qid); } =20 static void print_sg(struct iovec *sg, int cnt) @@ -1116,7 +1130,6 @@ static void coroutine_fn v9fs_getattr(void *opaque) uint64_t request_mask; V9fsStatDotl v9stat_dotl; V9fsPDU *pdu =3D opaque; - V9fsState *s =3D pdu->s; =20 retval =3D pdu_unmarshal(pdu, offset, "dq", &fid, &request_mask); if (retval < 0) { @@ -1137,7 +1150,10 @@ static void coroutine_fn v9fs_getattr(void *opaque) if (retval < 0) { goto out; } - stat_to_v9stat_dotl(s, &stbuf, &v9stat_dotl); + retval =3D stat_to_v9stat_dotl(pdu, &stbuf, &v9stat_dotl); + if (retval < 0) { + goto out; + } =20 /* fill st_gen if requested and supported by underlying fs */ if (request_mask & P9_STATS_GEN) { @@ -1377,7 +1393,10 @@ static void coroutine_fn v9fs_walk(void *opaque) if (err < 0) { goto out; } - stat_to_qid(&stbuf, &qid); + err =3D stat_to_qid(pdu, &stbuf, &qid); + if (err < 0) { + goto out; + } v9fs_path_copy(&dpath, &path); } memcpy(&qids[name_idx], &qid, sizeof(qid)); @@ -1477,7 +1496,10 @@ static void coroutine_fn v9fs_open(void *opaque) if (err < 0) { goto out; } - stat_to_qid(&stbuf, &qid); + err =3D stat_to_qid(pdu, &stbuf, &qid); + if (err < 0) { + goto out; + } if (S_ISDIR(stbuf.st_mode)) { err =3D v9fs_co_opendir(pdu, fidp); if (err < 0) { @@ -1587,7 +1609,10 @@ static void coroutine_fn v9fs_lcreate(void *opaque) fidp->flags |=3D FID_NON_RECLAIMABLE; } iounit =3D get_iounit(pdu, &fidp->path); - stat_to_qid(&stbuf, &qid); + err =3D stat_to_qid(pdu, &stbuf, &qid); + if (err < 0) { + goto out; + } err =3D pdu_marshal(pdu, offset, "Qd", &qid, iounit); if (err < 0) { goto out; @@ -2308,7 +2333,10 @@ static void coroutine_fn v9fs_create(void *opaque) } } iounit =3D get_iounit(pdu, &fidp->path); - stat_to_qid(&stbuf, &qid); + err =3D stat_to_qid(pdu, &stbuf, &qid); + if (err < 0) { + goto out; + } err =3D pdu_marshal(pdu, offset, "Qd", &qid, iounit); if (err < 0) { goto out; @@ -2365,7 +2393,10 @@ static void coroutine_fn v9fs_symlink(void *opaque) if (err < 0) { goto out; } - stat_to_qid(&stbuf, &qid); + err =3D stat_to_qid(pdu, &stbuf, &qid); + if (err < 0) { + goto out; + } err =3D pdu_marshal(pdu, offset, "Q", &qid); if (err < 0) { goto out; @@ -3033,7 +3064,10 @@ static void coroutine_fn v9fs_mknod(void *opaque) if (err < 0) { goto out; } - stat_to_qid(&stbuf, &qid); + err =3D stat_to_qid(pdu, &stbuf, &qid); + if (err < 0) { + goto out; + } err =3D pdu_marshal(pdu, offset, "Q", &qid); if (err < 0) { goto out; @@ -3191,7 +3225,10 @@ static void coroutine_fn v9fs_mkdir(void *opaque) if (err < 0) { goto out; } - stat_to_qid(&stbuf, &qid); + err =3D stat_to_qid(pdu, &stbuf, &qid); + if (err < 0) { + goto out; + } err =3D pdu_marshal(pdu, offset, "Q", &qid); if (err < 0) { goto out; @@ -3589,6 +3626,8 @@ int v9fs_device_realize_common(V9fsState *s, const V9= fsTransport *t, goto out; } =20 + s->dev_id =3D 0; + s->ctx.fst =3D &fse->fst; fsdev_throttle_init(s->ctx.fst); =20 diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index 5ced427..afb4ebd 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -252,6 +252,7 @@ struct V9fsState Error *migration_blocker; V9fsConf fsconf; V9fsQID root_qid; + dev_t dev_id; }; =20 /* 9p2000.L open flags */ --=20 1.8.3.1 From nobody Wed May 1 00:34:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1518113566901889.3693246235903; Thu, 8 Feb 2018 10:12:46 -0800 (PST) Received: from localhost ([::1]:58861 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejqgd-0005j8-Kl for importer@patchew.org; Thu, 08 Feb 2018 13:12:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35538) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejqU0-0002Sm-CM for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ejqTw-0006sd-8x for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:40 -0500 Received: from lhrrgout.huawei.com ([194.213.3.17]:43313 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ejqTw-0006rC-01 for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:36 -0500 Received: from lhreml704-cah.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id 8E3072CBA0887; Thu, 8 Feb 2018 17:59:30 +0000 (GMT) Received: from localhost.localdomain (10.204.62.86) by lhreml704-cah.china.huawei.com (10.201.108.45) with Microsoft SMTP Server id 14.3.361.1; Thu, 8 Feb 2018 17:59:23 +0000 From: To: , Date: Thu, 8 Feb 2018 19:00:18 +0100 Message-ID: <20180208180019.13683-4-antonios.motakis@huawei.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180208180019.13683-1-antonios.motakis@huawei.com> References: <20180208180019.13683-1-antonios.motakis@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.62.86] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 194.213.3.17 Subject: [Qemu-devel] [PATCH 3/4] 9pfs: stat_to_qid: use device as input to qid.path X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: veaceslav.falico@huawei.com, Eduard.Shishkin@huawei.com, andy.wangguoli@huawei.com, cota@braap.org, Antonios Motakis , Jani.Kokkonen@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Antonios Motakis To support multiple devices on the 9p share, and avoid qid path collisions we take the device id as input to generate a unique QID path. The lowest 48 bits of the path will be set equal to the file inode, and the top bits will be uniquely assigned based on the top 16 bits of the inode and the device id. Signed-off-by: Antonios Motakis --- hw/9pfs/9p.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++---= ---- hw/9pfs/9p.h | 13 ++++++++- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 4da858f..f434f05 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -25,6 +25,8 @@ #include "trace.h" #include "migration/blocker.h" #include "sysemu/qtest.h" +#include "exec/tb-hash-xx.h" +#include "qemu/qht.h" =20 int open_fd_hw; int total_open_fd; @@ -572,20 +574,82 @@ static void coroutine_fn virtfs_reset(V9fsPDU *pdu) P9_STAT_MODE_NAMED_PIPE | \ P9_STAT_MODE_SOCKET) =20 -/* This is the algorithm from ufs in spfs */ + +/* creative abuse of tb_hash_func7, which is based on xxhash */ +static uint32_t qpp_hash(QppEntry e) +{ + return tb_hash_func7(e.ino_prefix, e.dev, 0, 0, 0); +} + +static bool qpp_lookup_func(const void *obj, const void *userp) +{ + const QppEntry *e1 =3D obj, *e2 =3D userp; + return (e1->dev =3D=3D e2->dev) && (e1->ino_prefix =3D=3D e2->ino_pref= ix); +} + +static void qpp_table_remove(struct qht *ht, void *p, uint32_t h, void *up) +{ + g_free(p); +} + +static void qpp_table_destroy(struct qht *ht) +{ + qht_iter(ht, qpp_table_remove, NULL); + qht_destroy(ht); +} + +/* 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 + * the device id to the 16 highest bits of the QID path. The 48 lowest bits + * of the QID path equal to the lowest bits of the inode number. + * + * This takes advantage of the fact that inode number are usually not + * random but allocated sequentially, so we have fewer items to keep + * track of. + */ +static int qid_path_prefixmap(V9fsPDU *pdu, const struct stat *stbuf, + uint64_t *path) +{ + QppEntry lookup =3D { + .dev =3D stbuf->st_dev, + .ino_prefix =3D (uint16_t) (stbuf->st_ino >> 48) + }, *val; + uint32_t hash =3D qpp_hash(lookup); + + val =3D qht_lookup(&pdu->s->qpp_table, qpp_lookup_func, &lookup, hash); + + if (!val) { + if (pdu->s->qp_prefix_next =3D=3D 0) { + /* we ran out of prefixes */ + return -ENFILE; + } + + val =3D g_malloc0(sizeof(QppEntry)); + if (!val) { + return -ENOMEM; + } + *val =3D lookup; + + /* new unique inode prefix and device combo */ + val->qp_prefix =3D pdu->s->qp_prefix_next++; + qht_insert(&pdu->s->qpp_table, val, hash); + } + + *path =3D ((uint64_t)val->qp_prefix << 48) | (stbuf->st_ino & QPATH_IN= O_MASK); + return 0; +} + static int stat_to_qid(V9fsPDU *pdu, const struct stat *stbuf, V9fsQID *qi= dp) { - size_t size; + int err; =20 - if (pdu->s->dev_id =3D=3D 0) { - pdu->s->dev_id =3D stbuf->st_dev; - } else if (pdu->s->dev_id !=3D stbuf->st_dev) { - return -ENOSYS; + /* map inode+device to qid path (fast path) */ + err =3D qid_path_prefixmap(pdu, stbuf, &qidp->path); + if (err) { + return err; } =20 - memset(&qidp->path, 0, sizeof(qidp->path)); - size =3D MIN(sizeof(stbuf->st_ino), sizeof(qidp->path)); - memcpy(&qidp->path, &stbuf->st_ino, size); qidp->version =3D stbuf->st_mtime ^ (stbuf->st_size << 8); qidp->type =3D 0; if (S_ISDIR(stbuf->st_mode)) { @@ -3626,7 +3690,9 @@ int v9fs_device_realize_common(V9fsState *s, const V9= fsTransport *t, goto out; } =20 - s->dev_id =3D 0; + /* 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 =3D 1; /* reserve 0 to detect overflow */ =20 s->ctx.fst =3D &fse->fst; fsdev_throttle_init(s->ctx.fst); @@ -3641,6 +3707,7 @@ out: } g_free(s->tag); g_free(s->ctx.fs_root); + qpp_table_destroy(&s->qpp_table); v9fs_path_free(&path); } return rc; @@ -3653,6 +3720,7 @@ 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); g_free(s->ctx.fs_root); } =20 diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index afb4ebd..80428f7 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -8,6 +8,7 @@ #include "fsdev/9p-iov-marshal.h" #include "qemu/thread.h" #include "qemu/coroutine.h" +#include "qemu/qht.h" =20 enum { P9_TLERROR =3D 6, @@ -231,6 +232,15 @@ struct V9fsFidState V9fsFidState *rclm_lst; }; =20 +#define QPATH_INO_MASK (((unsigned long)1 << 48) - 1) + +/* QID path prefix entry, see stat_to_qid */ +typedef struct { + dev_t dev; + uint16_t ino_prefix; + uint16_t qp_prefix; +} QppEntry; + struct V9fsState { QLIST_HEAD(, V9fsPDU) free_list; @@ -252,7 +262,8 @@ struct V9fsState Error *migration_blocker; V9fsConf fsconf; V9fsQID root_qid; - dev_t dev_id; + struct qht qpp_table; + uint16_t qp_prefix_next; }; =20 /* 9p2000.L open flags */ --=20 1.8.3.1 From nobody Wed May 1 00:34:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1518113888512545.1997395630857; Thu, 8 Feb 2018 10:18:08 -0800 (PST) Received: from localhost ([::1]:59353 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejqlr-0001wh-JT for importer@patchew.org; Thu, 08 Feb 2018 13:18:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35513) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejqTz-0002S5-7D for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ejqTw-0006sc-8s for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:39 -0500 Received: from lhrrgout.huawei.com ([194.213.3.17]:43314 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ejqTv-0006rD-Vk for qemu-devel@nongnu.org; Thu, 08 Feb 2018 12:59:36 -0500 Received: from lhreml704-cah.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id 9EEF6204FE358; Thu, 8 Feb 2018 17:59:30 +0000 (GMT) Received: from localhost.localdomain (10.204.62.86) by lhreml704-cah.china.huawei.com (10.201.108.45) with Microsoft SMTP Server id 14.3.361.1; Thu, 8 Feb 2018 17:59:24 +0000 From: To: , Date: Thu, 8 Feb 2018 19:00:19 +0100 Message-ID: <20180208180019.13683-5-antonios.motakis@huawei.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180208180019.13683-1-antonios.motakis@huawei.com> References: <20180208180019.13683-1-antonios.motakis@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.62.86] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 194.213.3.17 Subject: [Qemu-devel] [PATCH 4/4] 9pfs: stat_to_qid: implement slow path X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: veaceslav.falico@huawei.com, Eduard.Shishkin@huawei.com, andy.wangguoli@huawei.com, cota@braap.org, Antonios Motakis , Jani.Kokkonen@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Antonios Motakis 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 --- 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); } =20 +static uint32_t qpf_hash(QpfEntry e) +{ + return tb_hash_func7(e.ino, e.dev, 0, 0, 0); +} + static bool qpp_lookup_func(const void *obj, const void *userp) { const QppEntry *e1 =3D obj, *e2 =3D userp; return (e1->dev =3D=3D e2->dev) && (e1->ino_prefix =3D=3D e2->ino_pref= ix); } =20 -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 =3D obj, *e2 =3D userp; + return (e1->dev =3D=3D e2->dev) && (e1->ino =3D=3D e2->ino); +} + +static void qp_table_remove(struct qht *ht, void *p, uint32_t h, void *up) { g_free(p); } =20 -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); } =20 +static int qid_path_fullmap(V9fsPDU *pdu, const struct stat *stbuf, + uint64_t *path) +{ + QpfEntry lookup =3D { + .dev =3D stbuf->st_dev, + .ino =3D stbuf->st_ino + }, *val; + uint32_t hash =3D 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 =3D qht_lookup(&pdu->s->qpf_table, qpf_lookup_func, &lookup, hash); + + if (!val) { + if (pdu->s->qp_fullpath_next =3D=3D 0) { + /* no more files can be mapped :'( */ + return -ENFILE; + } + + val =3D g_malloc0(sizeof(QppEntry)); + if (!val) { + return -ENOMEM; + } + *val =3D lookup; + + /* new unique inode and device combo */ + val->path =3D pdu->s->qp_fullpath_next++; + pdu->s->qp_fullpath_next &=3D QPATH_INO_MASK; + qht_insert(&pdu->s->qpf_table, val, hash); + } + + *path =3D 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) =20 /* map inode+device to qid path (fast path) */ err =3D qid_path_prefixmap(pdu, stbuf, &qidp->path); + if (err =3D=3D -ENFILE) { + /* fast path didn't work, fal back to full map */ + err =3D qid_path_fullmap(pdu, stbuf, &qidp->path); + } if (err) { return err; } @@ -3693,6 +3746,7 @@ int v9fs_device_realize_common(V9fsState *s, const V9= fsTransport *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 =3D 1; /* reserve 0 to detect overflow */ + s->qp_fullpath_next =3D 1; =20 s->ctx.fst =3D &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); } =20 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; =20 +/* 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; }; =20 /* 9p2000.L open flags */ --=20 1.8.3.1