Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 196818
b: refs/heads/master
c: 1a3cbbc
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Jens Axboe committed Apr 27, 2010
1 parent aec44f7 commit 334fe27
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 19 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: afc24d49c1e5dbeef745c1c1246f5ae6ebd97c71
refs/heads/master: 1a3cbbc5a5e8a66934aa0947896a4aca6fd77298
65 changes: 47 additions & 18 deletions trunk/fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,41 +661,70 @@ void bd_forget(struct inode *inode)
iput(bdev->bd_inode);
}

int bd_claim(struct block_device *bdev, void *holder)
/**
* bd_may_claim - test whether a block device can be claimed
* @bdev: block device of interest
* @whole: whole block device containing @bdev, may equal @bdev
* @holder: holder trying to claim @bdev
*
* Test whther @bdev can be claimed by @holder.
*
* CONTEXT:
* spin_lock(&bdev_lock).
*
* RETURNS:
* %true if @bdev can be claimed, %false otherwise.
*/
static bool bd_may_claim(struct block_device *bdev, struct block_device *whole,
void *holder)
{
int res;
spin_lock(&bdev_lock);

/* first decide result */
if (bdev->bd_holder == holder)
res = 0; /* already a holder */
return true; /* already a holder */
else if (bdev->bd_holder != NULL)
res = -EBUSY; /* held by someone else */
return false; /* held by someone else */
else if (bdev->bd_contains == bdev)
res = 0; /* is a whole device which isn't held */
return true; /* is a whole device which isn't held */

else if (bdev->bd_contains->bd_holder == bd_claim)
res = 0; /* is a partition of a device that is being partitioned */
else if (bdev->bd_contains->bd_holder != NULL)
res = -EBUSY; /* is a partition of a held device */
else if (whole->bd_holder == bd_claim)
return true; /* is a partition of a device that is being partitioned */
else if (whole->bd_holder != NULL)
return false; /* is a partition of a held device */
else
res = 0; /* is a partition of an un-held device */
return true; /* is a partition of an un-held device */
}

/* now impose change */
if (res==0) {
/**
* bd_claim - claim a block device
* @bdev: block device to claim
* @holder: holder trying to claim @bdev
*
* Try to claim @bdev.
*
* RETURNS:
* 0 if successful, -EBUSY if @bdev is already claimed.
*/
int bd_claim(struct block_device *bdev, void *holder)
{
struct block_device *whole = bdev->bd_contains;
int res = -EBUSY;

spin_lock(&bdev_lock);

if (bd_may_claim(bdev, whole, holder)) {
/* note that for a whole device bd_holders
* will be incremented twice, and bd_holder will
* be set to bd_claim before being set to holder
*/
bdev->bd_contains->bd_holders ++;
bdev->bd_contains->bd_holder = bd_claim;
whole->bd_holders++;
whole->bd_holder = bd_claim;
bdev->bd_holders++;
bdev->bd_holder = holder;
res = 0;
}

spin_unlock(&bdev_lock);
return res;
}

EXPORT_SYMBOL(bd_claim);

void bd_release(struct block_device *bdev)
Expand Down

0 comments on commit 334fe27

Please sign in to comment.