nbd: do not free spdk_nbd_disk with io outstanding
There is a race condition here, where kernel could have outstanding I/O to nbd device at the same time we terminate the nbd application. In this case, we cannot free the spdk_nbd_disk since it contains the io structure that will be referenced when the SPDK poller completes one of those I/O. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I1bde240af904957f4d2bfa358dc673105d266986 Reviewed-on: https://review.gerrithub.io/385927 Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Ziye Yang <optimistyzy@gmail.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
fa952fcd5a
commit
0441ffcc05
@ -46,6 +46,7 @@
|
||||
|
||||
struct nbd_io {
|
||||
enum spdk_bdev_io_type type;
|
||||
int ref;
|
||||
void *payload;
|
||||
|
||||
/* NOTE: for TRIM, this represents number of bytes to trim. */
|
||||
@ -97,13 +98,9 @@ is_write(enum spdk_bdev_io_type io_type)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
spdk_nbd_stop(struct spdk_nbd_disk *nbd)
|
||||
static void
|
||||
_nbd_stop(struct spdk_nbd_disk *nbd)
|
||||
{
|
||||
if (nbd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nbd->ch) {
|
||||
spdk_put_io_channel(nbd->ch);
|
||||
}
|
||||
@ -119,6 +116,19 @@ spdk_nbd_stop(struct spdk_nbd_disk *nbd)
|
||||
free(nbd);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_nbd_stop(struct spdk_nbd_disk *nbd)
|
||||
{
|
||||
if (nbd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
nbd->io.ref--;
|
||||
if (nbd->io.ref == 0) {
|
||||
_nbd_stop(nbd);
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t
|
||||
read_from_socket(int fd, void *buf, size_t length)
|
||||
{
|
||||
@ -169,6 +179,11 @@ nbd_io_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
||||
if (bdev_io != NULL) {
|
||||
spdk_bdev_free_io(bdev_io);
|
||||
}
|
||||
|
||||
io->ref--;
|
||||
if (io->ref == 0) {
|
||||
_nbd_stop(SPDK_CONTAINEROF(io, struct spdk_nbd_disk, io));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -177,6 +192,8 @@ nbd_submit_bdev_io(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
|
||||
{
|
||||
int rc;
|
||||
|
||||
io->ref++;
|
||||
|
||||
switch (io->type) {
|
||||
case SPDK_BDEV_IO_TYPE_READ:
|
||||
rc = spdk_bdev_read(desc, ch, io->payload, from_be64(&io->req.from),
|
||||
@ -376,6 +393,7 @@ spdk_nbd_start(struct spdk_bdev *bdev, const char *nbd_path)
|
||||
goto err;
|
||||
}
|
||||
|
||||
nbd->io.ref = 1;
|
||||
nbd->bdev = bdev;
|
||||
nbd->ch = spdk_bdev_get_io_channel(nbd->bdev_desc);
|
||||
nbd->buf_align = spdk_max(spdk_bdev_get_buf_align(bdev), 64);
|
||||
|
Loading…
Reference in New Issue
Block a user