Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 208283
b: refs/heads/master
c: a66b5ae
h: refs/heads/master
i:
  208281: 3087d9a
  208279: bd2a223
v: v3
  • Loading branch information
Daniel Stodden authored and Jens Axboe committed Aug 7, 2010
1 parent 498f609 commit ee70c9b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9897cb532382f075b337f7933b5a50f0ffc32d35
refs/heads/master: a66b5aebb7dc9e695dcb4b528906fd398b63f3d9
91 changes: 43 additions & 48 deletions trunk/drivers/block/xen-blkfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,39 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
return err;
}

static void xlvbd_release_gendisk(struct blkfront_info *info)
{
unsigned int minor, nr_minors;
unsigned long flags;

if (info->rq == NULL)
return;

spin_lock_irqsave(&blkif_io_lock, flags);

/* No more blkif_request(). */
blk_stop_queue(info->rq);

/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
spin_unlock_irqrestore(&blkif_io_lock, flags);

/* Flush gnttab callback work. Must be done with no locks held. */
flush_scheduled_work();

del_gendisk(info->gd);

minor = info->gd->first_minor;
nr_minors = info->gd->minors;
xlbd_release_minors(minor, nr_minors);

blk_cleanup_queue(info->rq);
info->rq = NULL;

put_disk(info->gd);
info->gd = NULL;
}

static void kick_pending_request_queues(struct blkfront_info *info)
{
if (!RING_FULL(&info->ring)) {
Expand Down Expand Up @@ -994,49 +1027,6 @@ static void blkfront_connect(struct blkfront_info *info)
info->is_ready = 1;
}

/**
* Handle the change of state of the backend to Closing. We must delete our
* device-layer structures now, to ensure that writes are flushed through to
* the backend. Once is this done, we can switch to Closed in
* acknowledgement.
*/
static void blkfront_closing(struct blkfront_info *info)
{
unsigned int minor, nr_minors;
unsigned long flags;


if (info->rq == NULL)
goto out;

spin_lock_irqsave(&blkif_io_lock, flags);

/* No more blkif_request(). */
blk_stop_queue(info->rq);

/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
spin_unlock_irqrestore(&blkif_io_lock, flags);

/* Flush gnttab callback work. Must be done with no locks held. */
flush_scheduled_work();

minor = info->gd->first_minor;
nr_minors = info->gd->minors;
del_gendisk(info->gd);
xlbd_release_minors(minor, nr_minors);

blk_cleanup_queue(info->rq);
info->rq = NULL;

put_disk(info->gd);
info->gd = NULL;

out:
if (info->xbdev)
xenbus_frontend_closed(info->xbdev);
}

/**
* Callback received when the backend's state changes.
*/
Expand Down Expand Up @@ -1073,8 +1063,11 @@ static void blkback_changed(struct xenbus_device *dev,
if (info->users > 0)
xenbus_dev_error(dev, -EBUSY,
"Device in use; refusing to close");
else
blkfront_closing(info);
else {
xlvbd_release_gendisk(info);
xenbus_frontend_closed(info->xbdev);
}

mutex_unlock(&bd->bd_mutex);
bdput(bd);
break;
Expand Down Expand Up @@ -1130,11 +1123,13 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
struct xenbus_device *dev = info->xbdev;

if (!dev) {
blkfront_closing(info);
xlvbd_release_gendisk(info);
kfree(info);
} else if (xenbus_read_driver_state(dev->otherend)
== XenbusStateClosing && info->is_ready)
blkfront_closing(info);
== XenbusStateClosing && info->is_ready) {
xlvbd_release_gendisk(info);
xenbus_frontend_closed(dev);
}
}
unlock_kernel();
return 0;
Expand Down

0 comments on commit ee70c9b

Please sign in to comment.