Skip to content

Commit

Permalink
rbd: avoid dropping extra reference in rbd_free_disk()
Browse files Browse the repository at this point in the history
I found during some failure injection testing that the call to
rbd_free_disk() in the error path of rbd_dev_probe_finish() was
dropping an extra reference to the disk queue.  The problem
occurred when put_disk tried to drop a reference to the disk's
queue.  A call to blk_cleanup_queue() just prior to that will have
also dropped a reference to the queue.

The problem is that the reference dropped by put_disk() is assumed
to have been taken by add_disk().  Our code has error paths that can
occur after the disk and its queue are initialized, but before the
call to add_disk(), and in those paths we won't have that extra
reference.

The fix is easy though.  In rbd_free_disk() we're already checking
the disk's GENHD_FL_UP flag.  That flag is an indication that
add_disk() has been called, so just call blk_cleanup_queue()
conditional on that flag being set.

This resolves:
    http://tracker.ceph.com/issues/4800

Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
  • Loading branch information
Alex Elder authored and Sage Weil committed May 2, 2013
1 parent f40eb34 commit a0cab92
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2844,10 +2844,12 @@ static void rbd_free_disk(struct rbd_device *rbd_dev)
if (!disk)
return;

if (disk->flags & GENHD_FL_UP)
rbd_dev->disk = NULL;
if (disk->flags & GENHD_FL_UP) {
del_gendisk(disk);
if (disk->queue)
blk_cleanup_queue(disk->queue);
if (disk->queue)
blk_cleanup_queue(disk->queue);
}
put_disk(disk);
}

Expand Down

0 comments on commit a0cab92

Please sign in to comment.