@@ -1381,54 +1381,62 @@ out:
v9fs_string_free(&aname);
}
-static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
+/* This is called by the IO thread */
+static void v9fs_stat_do_complete(void *opaque)
{
- if (err == -1) {
- err = -errno;
+ V9fsStatState *vs = (V9fsStatState *)opaque;
+ complete_pdu(vs->s, vs->pdu, vs->err);
+ v9fs_stat_free(&vs->v9stat);
+ qemu_free(vs);
+}
+
+/* This is called by the async thread. It does everything
+ * other than calling complete_pdu
+ */
+static void v9fs_stat_worker(ThreadletWork *work)
+{
+ V9fsStatState *vs = container_of(work, V9fsStatState, work);
+
+ vs->fidp = lookup_fid(vs->s, vs->fid);
+ if (vs->fidp == NULL) {
+ vs->err = -ENOENT;
goto out;
}
- err = stat_to_v9stat(s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
- if (err) {
+ qemu_rwmutex_rdlock(&global_rename_lock);
+ vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+ if (vs->err == -1) {
+ vs->err = -errno;
+ goto out;
+ }
+ vs->err = stat_to_v9stat(vs->s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
+ if (vs->err) {
goto out;
}
vs->offset += pdu_marshal(vs->pdu, vs->offset, "wS", 0, &vs->v9stat);
- err = vs->offset;
+ vs->err = vs->offset;
out:
- complete_pdu(s, vs->pdu, err);
- v9fs_stat_free(&vs->v9stat);
- qemu_free(vs);
+ qemu_rwmutex_unlock(&global_rename_lock);
+ v9fs_async_helper_done(v9fs_stat_do_complete, vs);
}
static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
{
- int32_t fid;
V9fsStatState *vs;
- ssize_t err = 0;
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
vs->offset = 7;
+ vs->s = s;
memset(&vs->v9stat, 0, sizeof(vs->v9stat));
- pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
-
- vs->fidp = lookup_fid(s, fid);
- if (vs->fidp == NULL) {
- err = -ENOENT;
- goto out;
- }
+ pdu_unmarshal(vs->pdu, vs->offset, "d", &vs->fid);
- err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
- v9fs_stat_post_lstat(s, vs, err);
+ vs->work.func = v9fs_stat_worker;
+ submit_threadlet(&vs->work);
return;
-
-out:
- complete_pdu(s, vs->pdu, err);
- v9fs_stat_free(&vs->v9stat);
- qemu_free(vs);
}
static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs,
@@ -248,6 +248,10 @@ typedef struct V9fsStatState {
V9fsStat v9stat;
V9fsFidState *fidp;
struct stat stbuf;
+ V9fsState *s;
+ int32_t fid;
+ int32_t err;
+ ThreadletWork work;
} V9fsStatState;
typedef struct V9fsStatDotl {