mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
9p-for-6.2-rc1
- improve p9_check_errors to check buffer size instead of msize when possible (e.g. not zero-copy) - some more syzbot and KCSAN fixes - minor headers include cleanup -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE/IPbcYBuWt0zoYhOq06b7GqY5nAFAmOljPwACgkQq06b7GqY 5nDRjw//aJU+tdcKCMije/ul4hMWDlvMwxn7x6p0ELdomefs+ykS/knBxXSVIoEs PrbVJVZVqOOOAn/IwWe8cMBD+hal0fLUErRbfrtzmOdkiF7z8PavJ209OeJLKBgD ffL+bq6FhcVC6jVXcwVHoZkX9bb4pnM7/lsJrO0UjBw+fT3ceqtK0vsTa+R2xEOj 9lOS5124u69GVa9UvwQzqHko+UUx5T6XlULZYjNBEdtJqGULGi2oAABrae64R3N2 auaj5LRKzAFOx4zkJ+crCH1h08uZ4bfTyCHpfCeTHwWb1duKD3u4jMq9PhdetF4E A6NYnOdeMxbV/sZfFOjjNWQrzP1TQJLmF6IVGSZkVQrlCjrZh7xQ5dr/AHrKr6be U+NXb0UCmAS6/Gs7Sxq5jnihDHzJ4rYG+oFdYdNrwPrrpQXsYmmRh+bm61m/t40T 2JxBIiSt2KWL487AHsKisb6OsiH65N1ojntO5QJObZId4UdnhFJU6OaAzqv0Cojv mqKlZ0UPyxICXNCL227w+SdDFgK25efdLF1Z1547hS5DO0+43oWAtnvd3KrRpjZ6 CmV9ARvdhHt49lNedbxmJAre5FusJQLeULuRzhMbd4mdcG7mKAmGTdM3u+AlFRIu Te1ZotTJXxs16Yn/whWRShAooUnK9FbXzC3kViiibziYZlCfK+s= =xLkl -----END PGP SIGNATURE----- Merge tag '9p-for-6.2-rc1' of https://github.com/martinetd/linux Pull 9p updates from Dominique Martinet: - improve p9_check_errors to check buffer size instead of msize when possible (e.g. not zero-copy) - some more syzbot and KCSAN fixes - minor headers include cleanup * tag '9p-for-6.2-rc1' of https://github.com/martinetd/linux: 9p/client: fix data race on req->status net/9p: fix response size check in p9_check_errors() net/9p: distinguish zero-copy requests 9p/xen: do not memcpy header into req->rc 9p: set req refcount to zero to avoid uninitialized usage 9p/net: Remove unneeded idr.h #include 9p/fs: Remove unneeded idr.h #include
This commit is contained in:
commit
e3b862ed89
@ -11,7 +11,6 @@
|
||||
#include <linux/fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/idr.h>
|
||||
#include <net/9p/9p.h>
|
||||
#include <net/9p/client.h>
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/parser.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <net/9p/9p.h>
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/uio.h>
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <net/9p/9p.h>
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/fscache.h>
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <net/9p/9p.h>
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/xattr.h>
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/xattr.h>
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <linux/inet.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/statfs.h>
|
||||
|
@ -531,6 +531,7 @@ struct p9_rstatfs {
|
||||
* @offset: used by marshalling routines to track current position in buffer
|
||||
* @capacity: used by marshalling routines to track total malloc'd capacity
|
||||
* @sdata: payload
|
||||
* @zc: whether zero-copy is used
|
||||
*
|
||||
* &p9_fcall represents the structure for all 9P RPC
|
||||
* transactions. Requests are packaged into fcalls, and reponses
|
||||
@ -549,6 +550,7 @@ struct p9_fcall {
|
||||
|
||||
struct kmem_cache *cache;
|
||||
u8 *sdata;
|
||||
bool zc;
|
||||
};
|
||||
|
||||
int p9_errstr2errno(char *errstr, int len);
|
||||
|
@ -297,6 +297,11 @@ p9_tag_alloc(struct p9_client *c, int8_t type, uint t_size, uint r_size,
|
||||
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.
|
||||
*/
|
||||
refcount_set(&req->refcount, 0);
|
||||
init_waitqueue_head(&req->wq);
|
||||
INIT_LIST_HEAD(&req->req_list);
|
||||
|
||||
@ -438,7 +443,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
|
||||
* the status change is visible to another thread
|
||||
*/
|
||||
smp_wmb();
|
||||
req->status = status;
|
||||
WRITE_ONCE(req->status, status);
|
||||
|
||||
wake_up(&req->wq);
|
||||
p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
|
||||
@ -514,10 +519,9 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
|
||||
int ecode;
|
||||
|
||||
err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
|
||||
if (req->rc.size >= c->msize) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"requested packet size too big: %d\n",
|
||||
req->rc.size);
|
||||
if (req->rc.size > req->rc.capacity && !req->rc.zc) {
|
||||
pr_err("requested packet size too big: %d does not fit %zu (type=%d)\n",
|
||||
req->rc.size, req->rc.capacity, req->rc.id);
|
||||
return -EIO;
|
||||
}
|
||||
/* dump the response from server
|
||||
@ -600,7 +604,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
|
||||
/* if we haven't received a response for oldreq,
|
||||
* remove it from the list
|
||||
*/
|
||||
if (oldreq->status == REQ_STATUS_SENT) {
|
||||
if (READ_ONCE(oldreq->status) == REQ_STATUS_SENT) {
|
||||
if (c->trans_mod->cancelled)
|
||||
c->trans_mod->cancelled(c, oldreq);
|
||||
}
|
||||
@ -680,6 +684,9 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
|
||||
if (IS_ERR(req))
|
||||
return req;
|
||||
|
||||
req->tc.zc = false;
|
||||
req->rc.zc = false;
|
||||
|
||||
if (signal_pending(current)) {
|
||||
sigpending = 1;
|
||||
clear_thread_flag(TIF_SIGPENDING);
|
||||
@ -697,7 +704,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
|
||||
}
|
||||
again:
|
||||
/* Wait for the response */
|
||||
err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
|
||||
err = wait_event_killable(req->wq,
|
||||
READ_ONCE(req->status) >= REQ_STATUS_RCVD);
|
||||
|
||||
/* Make sure our req is coherent with regard to updates in other
|
||||
* threads - echoes to wmb() in the callback
|
||||
@ -711,7 +719,7 @@ again:
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (req->status == REQ_STATUS_ERROR) {
|
||||
if (READ_ONCE(req->status) == REQ_STATUS_ERROR) {
|
||||
p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
|
||||
err = req->t_err;
|
||||
}
|
||||
@ -724,7 +732,7 @@ again:
|
||||
p9_client_flush(c, req);
|
||||
|
||||
/* if we received the response anyway, don't signal error */
|
||||
if (req->status == REQ_STATUS_RCVD)
|
||||
if (READ_ONCE(req->status) == REQ_STATUS_RCVD)
|
||||
err = 0;
|
||||
}
|
||||
recalc_sigpending:
|
||||
@ -778,6 +786,9 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
|
||||
if (IS_ERR(req))
|
||||
return req;
|
||||
|
||||
req->tc.zc = true;
|
||||
req->rc.zc = true;
|
||||
|
||||
if (signal_pending(current)) {
|
||||
sigpending = 1;
|
||||
clear_thread_flag(TIF_SIGPENDING);
|
||||
@ -793,7 +804,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
|
||||
if (err != -ERESTARTSYS)
|
||||
goto recalc_sigpending;
|
||||
}
|
||||
if (req->status == REQ_STATUS_ERROR) {
|
||||
if (READ_ONCE(req->status) == REQ_STATUS_ERROR) {
|
||||
p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
|
||||
err = req->t_err;
|
||||
}
|
||||
@ -806,7 +817,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
|
||||
p9_client_flush(c, req);
|
||||
|
||||
/* if we received the response anyway, don't signal error */
|
||||
if (req->status == REQ_STATUS_RCVD)
|
||||
if (READ_ONCE(req->status) == REQ_STATUS_RCVD)
|
||||
err = 0;
|
||||
}
|
||||
recalc_sigpending:
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <linux/un.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/parser.h>
|
||||
#include <linux/slab.h>
|
||||
@ -202,11 +201,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
|
||||
|
||||
list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
|
||||
list_move(&req->req_list, &cancel_list);
|
||||
req->status = REQ_STATUS_ERROR;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_ERROR);
|
||||
}
|
||||
list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
|
||||
list_move(&req->req_list, &cancel_list);
|
||||
req->status = REQ_STATUS_ERROR;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_ERROR);
|
||||
}
|
||||
|
||||
spin_unlock(&m->req_lock);
|
||||
@ -467,7 +466,7 @@ static void p9_write_work(struct work_struct *work)
|
||||
|
||||
req = list_entry(m->unsent_req_list.next, struct p9_req_t,
|
||||
req_list);
|
||||
req->status = REQ_STATUS_SENT;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_SENT);
|
||||
p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
|
||||
list_move_tail(&req->req_list, &m->req_list);
|
||||
|
||||
@ -676,7 +675,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
|
||||
return m->err;
|
||||
|
||||
spin_lock(&m->req_lock);
|
||||
req->status = REQ_STATUS_UNSENT;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_UNSENT);
|
||||
list_add_tail(&req->req_list, &m->unsent_req_list);
|
||||
spin_unlock(&m->req_lock);
|
||||
|
||||
@ -703,7 +702,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
|
||||
|
||||
if (req->status == REQ_STATUS_UNSENT) {
|
||||
list_del(&req->req_list);
|
||||
req->status = REQ_STATUS_FLSHD;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_FLSHD);
|
||||
p9_req_put(client, req);
|
||||
ret = 0;
|
||||
}
|
||||
@ -732,7 +731,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
|
||||
* remove it from the list.
|
||||
*/
|
||||
list_del(&req->req_list);
|
||||
req->status = REQ_STATUS_FLSHD;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_FLSHD);
|
||||
spin_unlock(&m->req_lock);
|
||||
|
||||
p9_req_put(client, req);
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <linux/un.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/parser.h>
|
||||
#include <linux/semaphore.h>
|
||||
@ -507,7 +506,7 @@ dont_need_post_recv:
|
||||
* because doing if after could erase the REQ_STATUS_RCVD
|
||||
* status in case of a very fast reply.
|
||||
*/
|
||||
req->status = REQ_STATUS_SENT;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_SENT);
|
||||
err = ib_post_send(rdma->qp, &wr, NULL);
|
||||
if (err)
|
||||
goto send_error;
|
||||
@ -517,7 +516,7 @@ dont_need_post_recv:
|
||||
|
||||
/* Handle errors that happened during or while preparing the send: */
|
||||
send_error:
|
||||
req->status = REQ_STATUS_ERROR;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_ERROR);
|
||||
kfree(c);
|
||||
p9_debug(P9_DEBUG_ERROR, "Error %d in rdma_request()\n", err);
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <linux/un.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/slab.h>
|
||||
@ -263,7 +262,7 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
|
||||
|
||||
p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
|
||||
|
||||
req->status = REQ_STATUS_SENT;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_SENT);
|
||||
req_retry:
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
|
||||
@ -469,7 +468,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
|
||||
inlen = n;
|
||||
}
|
||||
}
|
||||
req->status = REQ_STATUS_SENT;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_SENT);
|
||||
req_retry_pinned:
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
|
||||
@ -532,9 +531,10 @@ req_retry_pinned:
|
||||
spin_unlock_irqrestore(&chan->lock, flags);
|
||||
kicked = 1;
|
||||
p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
|
||||
err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
|
||||
err = wait_event_killable(req->wq,
|
||||
READ_ONCE(req->status) >= REQ_STATUS_RCVD);
|
||||
// RERROR needs reply (== error string) in static data
|
||||
if (req->status == REQ_STATUS_RCVD &&
|
||||
if (READ_ONCE(req->status) == REQ_STATUS_RCVD &&
|
||||
unlikely(req->rc.sdata[4] == P9_RERROR))
|
||||
handle_rerror(req, in_hdr_len, offs, in_pages);
|
||||
|
||||
|
@ -157,7 +157,7 @@ again:
|
||||
&masked_prod, masked_cons,
|
||||
XEN_9PFS_RING_SIZE(ring));
|
||||
|
||||
p9_req->status = REQ_STATUS_SENT;
|
||||
WRITE_ONCE(p9_req->status, REQ_STATUS_SENT);
|
||||
virt_wmb(); /* write ring before updating pointer */
|
||||
prod += size;
|
||||
ring->intf->out_prod = prod;
|
||||
@ -212,11 +212,13 @@ static void p9_xen_response(struct work_struct *work)
|
||||
dev_warn(&priv->dev->dev,
|
||||
"requested packet size too big: %d for tag %d with capacity %zd\n",
|
||||
h.size, h.tag, req->rc.capacity);
|
||||
req->status = REQ_STATUS_ERROR;
|
||||
WRITE_ONCE(req->status, REQ_STATUS_ERROR);
|
||||
goto recv_error;
|
||||
}
|
||||
|
||||
memcpy(&req->rc, &h, sizeof(h));
|
||||
req->rc.size = h.size;
|
||||
req->rc.id = h.id;
|
||||
req->rc.tag = h.tag;
|
||||
req->rc.offset = 0;
|
||||
|
||||
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE(ring));
|
||||
|
Loading…
Reference in New Issue
Block a user