On 02/09/2018 09:13 AM, Greg Kurz wrote:
On Thu, 8 Feb 2018 19:00:18 +0100
<antonios.mota...@huawei.com> wrote:

From: Antonios Motakis <antonios.mota...@huawei.com>

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.

+/* 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 = {
+        .dev = stbuf->st_dev,
+        .ino_prefix = (uint16_t) (stbuf->st_ino >> 48)
+    }, *val;
+    uint32_t hash = qpp_hash(lookup);
+    val = qht_lookup(&pdu->s->qpp_table, qpp_lookup_func, &lookup, hash);
+    if (!val) {
+        if (pdu->s->qp_prefix_next == 0) {
+            /* we ran out of prefixes */
+            return -ENFILE;

Not sure this errno would make sense for guest syscalls that don't open
file descriptors... Maybe ENOENT ?

Cc'ing Eric for insights.

Actually, it makes sense to me:

ENFILE 23 Too many open files in system

You only get here if the hash table filled up, which means there are indeed too many open files (even if this syscall wasn't opening a file). In fact, ENFILE is usually associated with running into ulimit restrictions, and come to think of it, you are more likely to hit your ulimit than you are to run into a hash collision (so this code may be very hard to reach in practice, but if you do reach it, it behaves similarly to what you were more likely to hit in the first place).

ENOENT implies the file doesn't exist - but here, the file exists but we can't open it because we're out of resources for tracking it.

Also, POSIX permits returning specific errno codes that aren't otherwise listed for a syscall if the usual semantics of that errno code are indeed the reason for the failure (you should prefer to fail with errno codes documented by POSIX where possible, but POSIX does not limit you to just that set).

Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Reply via email to