Re: nbd oops on unload. [PATCH x2]

From: Paul Clements
Date: Wed Feb 18 2004 - 17:06:43 EST


Paul Clements wrote:

> Dave Jones wrote:
> > modprobe nbd ; rmmod nbd was enough to reproduce this one..
> > (2.6.3rc4)

> Ahh, cleanup was being done in the wrong order.
>
> Patch coming shortly...

Here it is, as well as another to fix some return codes (so nbd-client
can exit with the proper error code, rather than 0, when an error
occurs).

Tested against 2.6.3-rc2. Please apply.

Thanks,
Paul--- 2_6_3_rc2/drivers/block/nbd.c.ERROR_RETURN_FIXES Wed Feb 18 12:32:42 2004
+++ 2_6_3_rc2/drivers/block/nbd.c Wed Feb 18 12:44:50 2004
@@ -751,8 +751,7 @@ static int __init nbd_init(void)
return 0;
out:
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);
}
return err;
@@ -764,9 +763,8 @@ static void __exit nbd_cleanup(void)
for (i = 0; i < MAX_NBD; i++) {
struct gendisk *disk = nbd_dev[i].disk;
if (disk) {
- if (disk->queue)
- blk_cleanup_queue(disk->queue);
del_gendisk(disk);
+ blk_cleanup_queue(disk->queue);
put_disk(disk);
}
}
--- 2_6_3_rc2/drivers/block/nbd.c.PRISTINE Tue Feb 17 13:46:40 2004
+++ 2_6_3_rc2/drivers/block/nbd.c Wed Feb 18 12:29:15 2004
@@ -221,6 +221,8 @@ static int sock_xmit(struct socket *sock
printk(KERN_ERR "nbd: %s - sock=%p at buf=%p, size=%d returned %d.\n",
send? "send": "receive", sock, buf, size, result);
#endif
+ if (result == 0)
+ result = -EPIPE; /* short read */
break;
}
size -= result;
@@ -309,7 +311,7 @@ void nbd_send_req(struct nbd_device *lo,
up(&lo->tx_lock);
return;

- error_out:
+error_out:
up(&lo->tx_lock);
req->errors++;
}
@@ -358,23 +360,22 @@ struct request *nbd_read_stat(struct nbd
if (result <= 0) {
printk(KERN_ERR "%s: Receive control failed (result %d)\n",
lo->disk->disk_name, result);
- lo->harderror = result;
- return NULL;
+ goto harderror;
}
req = nbd_find_request(lo, reply.handle);
if (req == NULL) {
printk(KERN_ERR "%s: Unexpected reply (%p)\n",
lo->disk->disk_name, reply.handle);
- lo->harderror = result;
- return NULL;
+ result = -EBADR;
+ goto harderror;
}

if (ntohl(reply.magic) != NBD_REPLY_MAGIC) {
printk(KERN_ERR "%s: Wrong magic (0x%lx)\n",
lo->disk->disk_name,
(unsigned long)ntohl(reply.magic));
- lo->harderror = result;
- return NULL;
+ result = -EPROTO;
+ goto harderror;
}
if (ntohl(reply.error)) {
printk(KERN_ERR "%s: Other side returned error (%d)\n",
@@ -396,8 +397,7 @@ struct request *nbd_read_stat(struct nbd
printk(KERN_ERR "%s: Receive data failed (result %d)\n",
lo->disk->disk_name,
result);
- lo->harderror = result;
- return NULL;
+ goto harderror;
}
dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
lo->disk->disk_name, req, bvec->bv_len);
@@ -405,6 +405,9 @@ struct request *nbd_read_stat(struct nbd
}
}
return req;
+harderror:
+ lo->harderror = result;
+ return NULL;
}

void nbd_do_it(struct nbd_device *lo)
@@ -416,8 +419,6 @@ void nbd_do_it(struct nbd_device *lo)
#endif
while ((req = nbd_read_stat(lo)) != NULL)
nbd_end_request(req);
- printk(KERN_NOTICE "%s: req should never be null\n",
- lo->disk->disk_name);
return;
}