--- x/net/9p/client.c +++ y/net/9p/client.c @@ -181,11 +181,18 @@ p9_tag_alloc(struct p9_client *c, int8_t p9pdu_reset(&req->rc); req->t_err = 0; req->status = REQ_STATUS_ALLOC; - /* refcount needs to be set to 0 before inserting into the idr - * so p9_tag_lookup does not accept a request that is not fully - * initialized. refcount_set to 2 below will mark request ready. + req->tc.tag = -1; + /* Init ref to two because in the general case there is one ref + * that is put asynchronously by a writer thread, one ref + * temporarily given by p9_tag_lookup and put by p9_client_cb + * in the recv thread, and one ref put by p9_req_put in the + * main thread. The only exception is virtio that does not use + * p9_tag_lookup but does not have a writer thread either + * (the write happens synchronously in the request/zc_request + * callback), so p9_client_cb eats the second ref there + * as the pointer is duplicated directly by virtqueue_add_sgs() */ - refcount_set(&req->refcount, 0); + refcount_set(&req->refcount, 2); init_waitqueue_head(&req->wq); INIT_LIST_HEAD(&req->req_list); @@ -202,18 +209,6 @@ p9_tag_alloc(struct p9_client *c, int8_t if (tag < 0) goto free; - /* Init ref to two because in the general case there is one ref - * that is put asynchronously by a writer thread, one ref - * temporarily given by p9_tag_lookup and put by p9_client_cb - * in the recv thread, and one ref put by p9_req_put in the - * main thread. The only exception is virtio that does not use - * p9_tag_lookup but does not have a writer thread either - * (the write happens synchronously in the request/zc_request - * callback), so p9_client_cb eats the second ref there - * as the pointer is duplicated directly by virtqueue_add_sgs() - */ - refcount_set(&req->refcount, 2); - return req; free: