Commit 086a0782 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] NBD rmmod oops fix

From: Paul Clements <Paul.Clements@SteelEye.com>

Fix a module unload oops, as well as fix some return codes (so nbd-client
can exit with the proper error code, rather than 0, when an error occurs).
parent 562123b5
...@@ -221,6 +221,8 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, ...@@ -221,6 +221,8 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size,
printk(KERN_ERR "nbd: %s - sock=%p at buf=%p, size=%d returned %d.\n", printk(KERN_ERR "nbd: %s - sock=%p at buf=%p, size=%d returned %d.\n",
send? "send": "receive", sock, buf, size, result); send? "send": "receive", sock, buf, size, result);
#endif #endif
if (result == 0)
result = -EPIPE; /* short read */
break; break;
} }
size -= result; size -= result;
...@@ -309,7 +311,7 @@ void nbd_send_req(struct nbd_device *lo, struct request *req) ...@@ -309,7 +311,7 @@ void nbd_send_req(struct nbd_device *lo, struct request *req)
up(&lo->tx_lock); up(&lo->tx_lock);
return; return;
error_out: error_out:
up(&lo->tx_lock); up(&lo->tx_lock);
req->errors++; req->errors++;
} }
...@@ -358,23 +360,22 @@ struct request *nbd_read_stat(struct nbd_device *lo) ...@@ -358,23 +360,22 @@ struct request *nbd_read_stat(struct nbd_device *lo)
if (result <= 0) { if (result <= 0) {
printk(KERN_ERR "%s: Receive control failed (result %d)\n", printk(KERN_ERR "%s: Receive control failed (result %d)\n",
lo->disk->disk_name, result); lo->disk->disk_name, result);
lo->harderror = result; goto harderror;
return NULL;
} }
req = nbd_find_request(lo, reply.handle); req = nbd_find_request(lo, reply.handle);
if (req == NULL) { if (req == NULL) {
printk(KERN_ERR "%s: Unexpected reply (%p)\n", printk(KERN_ERR "%s: Unexpected reply (%p)\n",
lo->disk->disk_name, reply.handle); lo->disk->disk_name, reply.handle);
lo->harderror = result; result = -EBADR;
return NULL; goto harderror;
} }
if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { if (ntohl(reply.magic) != NBD_REPLY_MAGIC) {
printk(KERN_ERR "%s: Wrong magic (0x%lx)\n", printk(KERN_ERR "%s: Wrong magic (0x%lx)\n",
lo->disk->disk_name, lo->disk->disk_name,
(unsigned long)ntohl(reply.magic)); (unsigned long)ntohl(reply.magic));
lo->harderror = result; result = -EPROTO;
return NULL; goto harderror;
} }
if (ntohl(reply.error)) { if (ntohl(reply.error)) {
printk(KERN_ERR "%s: Other side returned error (%d)\n", printk(KERN_ERR "%s: Other side returned error (%d)\n",
...@@ -396,8 +397,7 @@ struct request *nbd_read_stat(struct nbd_device *lo) ...@@ -396,8 +397,7 @@ struct request *nbd_read_stat(struct nbd_device *lo)
printk(KERN_ERR "%s: Receive data failed (result %d)\n", printk(KERN_ERR "%s: Receive data failed (result %d)\n",
lo->disk->disk_name, lo->disk->disk_name,
result); result);
lo->harderror = result; goto harderror;
return NULL;
} }
dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
lo->disk->disk_name, req, bvec->bv_len); lo->disk->disk_name, req, bvec->bv_len);
...@@ -405,6 +405,9 @@ struct request *nbd_read_stat(struct nbd_device *lo) ...@@ -405,6 +405,9 @@ struct request *nbd_read_stat(struct nbd_device *lo)
} }
} }
return req; return req;
harderror:
lo->harderror = result;
return NULL;
} }
void nbd_do_it(struct nbd_device *lo) void nbd_do_it(struct nbd_device *lo)
...@@ -416,8 +419,6 @@ void nbd_do_it(struct nbd_device *lo) ...@@ -416,8 +419,6 @@ void nbd_do_it(struct nbd_device *lo)
#endif #endif
while ((req = nbd_read_stat(lo)) != NULL) while ((req = nbd_read_stat(lo)) != NULL)
nbd_end_request(req); nbd_end_request(req);
printk(KERN_NOTICE "%s: req should never be null\n",
lo->disk->disk_name);
return; return;
} }
...@@ -751,7 +752,6 @@ static int __init nbd_init(void) ...@@ -751,7 +752,6 @@ static int __init nbd_init(void)
return 0; return 0;
out: out:
while (i--) { while (i--) {
if (nbd_dev[i].disk->queue)
blk_cleanup_queue(nbd_dev[i].disk->queue); blk_cleanup_queue(nbd_dev[i].disk->queue);
put_disk(nbd_dev[i].disk); put_disk(nbd_dev[i].disk);
} }
...@@ -764,9 +764,8 @@ static void __exit nbd_cleanup(void) ...@@ -764,9 +764,8 @@ static void __exit nbd_cleanup(void)
for (i = 0; i < MAX_NBD; i++) { for (i = 0; i < MAX_NBD; i++) {
struct gendisk *disk = nbd_dev[i].disk; struct gendisk *disk = nbd_dev[i].disk;
if (disk) { if (disk) {
if (disk->queue)
blk_cleanup_queue(disk->queue);
del_gendisk(disk); del_gendisk(disk);
blk_cleanup_queue(disk->queue);
put_disk(disk); put_disk(disk);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment