zero copy error fix
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: GPGTools - http://gpgtools.org iQIcBAABAgAGBQJRtjfAAAoJEDZk62b0Tg6xEHcP/jtZbupCJBVmjvI5zBDjn4NT RnOoaZLz4ks1OTj2WkhkdMe7/dNh+Dlq/w9F9nw4jOZhkSN90cgDZJqK/otHqh3R GpXEwNS5NLysTu9qlA2Kd49C77KynafEUtFR4k0zSB/q8Uh+g8D480bps1xBeIUx ATlBSuYPy6SZM1PWqgllnP7IzATQtaHJSQ8uXCkfSneG+dj+13Fq9LngH7DCpKA6 T4bU8Mx8kXlR0RcVtjjqFAf7TmOe05XG/WhgsaX5gGcpxuZ5FajCaIZeuD1rQ63K jLKA56VxUGa5FU6ZBZH0I+52xhdceByJdFcTW8X8fhXU6m82NYhKnMv64QZ+UjT0 F2vNlzW7SkYvnMkjvxor/JLyi0OKIrMfElPYcuMW8pU5AVV9Hzf0M1NHLCeM2CNn JoghVzOPcUSistYldAJkivCcGi9sEgNadTsBrU1TM8FwkaHboUXprNf8xn2SRm1V iD/25/voPqbsVPtDSO9YsVEi6NldLx07yQwJy34jJ1D5Qw4MPtfPlUTLT17ikCc4 kjY1fiov+HOcEeCse1X3IxqEB3RK/KTR6NUqOk1yY2DlLxU1ZhJfrpelOTDV9iXc 5Ra71ebsBYb2gQqk6+do/IUxKMiLBGrt5l2KLq2ZdhWYn8Fr8O7B5gaX9BH8aOwH L5ROAeZxkgSJBjuKMcsi =+vsA -----END PGP SIGNATURE----- Merge tag '9p-3.10-bug-fix-1' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs Pull net/9p bug fix from Eric Van Hensbergen: "zero copy error fix" * tag '9p-3.10-bug-fix-1' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: net/9p: Handle error in zero copy request correctly for 9p2000.u
This commit is contained in:
commit
1b79821fe7
1 changed files with 18 additions and 37 deletions
|
@ -562,36 +562,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
|
|||
|
||||
if (!p9_is_proto_dotl(c)) {
|
||||
/* Error is reported in string format */
|
||||
uint16_t len;
|
||||
/* 7 = header size for RERROR, 2 is the size of string len; */
|
||||
int inline_len = in_hdrlen - (7 + 2);
|
||||
int len;
|
||||
/* 7 = header size for RERROR; */
|
||||
int inline_len = in_hdrlen - 7;
|
||||
|
||||
/* Read the size of error string */
|
||||
err = p9pdu_readf(req->rc, c->proto_version, "w", &len);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
ename = kmalloc(len + 1, GFP_NOFS);
|
||||
if (!ename) {
|
||||
err = -ENOMEM;
|
||||
len = req->rc->size - req->rc->offset;
|
||||
if (len > (P9_ZC_HDR_SZ - 7)) {
|
||||
err = -EFAULT;
|
||||
goto out_err;
|
||||
}
|
||||
if (len <= inline_len) {
|
||||
/* We have error in protocol buffer itself */
|
||||
if (pdu_read(req->rc, ename, len)) {
|
||||
err = -EFAULT;
|
||||
goto out_free;
|
||||
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Part of the data is in user space buffer.
|
||||
*/
|
||||
if (pdu_read(req->rc, ename, inline_len)) {
|
||||
err = -EFAULT;
|
||||
goto out_free;
|
||||
|
||||
}
|
||||
ename = &req->rc->sdata[req->rc->offset];
|
||||
if (len > inline_len) {
|
||||
/* We have error in external buffer */
|
||||
if (kern_buf) {
|
||||
memcpy(ename + inline_len, uidata,
|
||||
len - inline_len);
|
||||
|
@ -600,19 +583,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
|
|||
uidata, len - inline_len);
|
||||
if (err) {
|
||||
err = -EFAULT;
|
||||
goto out_free;
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
ename[len] = 0;
|
||||
if (p9_is_proto_dotu(c)) {
|
||||
/* For dotu we also have error code */
|
||||
err = p9pdu_readf(req->rc,
|
||||
c->proto_version, "d", &ecode);
|
||||
if (err)
|
||||
goto out_free;
|
||||
ename = NULL;
|
||||
err = p9pdu_readf(req->rc, c->proto_version, "s?d",
|
||||
&ename, &ecode);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
if (p9_is_proto_dotu(c))
|
||||
err = -ecode;
|
||||
}
|
||||
|
||||
if (!err || !IS_ERR_VALUE(err)) {
|
||||
err = p9_errstr2errno(ename, strlen(ename));
|
||||
|
||||
|
@ -628,8 +611,6 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
|
|||
}
|
||||
return err;
|
||||
|
||||
out_free:
|
||||
kfree(ename);
|
||||
out_err:
|
||||
p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
|
||||
return err;
|
||||
|
|
Loading…
Reference in a new issue