Commit f57dea91 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] When a partition is claimed, claim the whole device

From: NeilBrown <neilb@cse.unsw.edu.au>

Current devices can be 'claimed' by filesystems (when mounting) or
md/raid (when being included in an array) or 'raw' or ....
This stop concurrent access by these systems.

However it is still possible for one system to claim the whole device
and a second system to claim one partition, which is not good.

With this patch, when a partition is claimed, the whole device is 
claimed for partitioning.  So you cannot have a partition and the
whole devices claimed at the same time (except if the whole device
is claimed for partitioning).
parent d55158b5
...@@ -419,12 +419,34 @@ void bd_forget(struct inode *inode) ...@@ -419,12 +419,34 @@ void bd_forget(struct inode *inode)
int bd_claim(struct block_device *bdev, void *holder) int bd_claim(struct block_device *bdev, void *holder)
{ {
int res = -EBUSY; int res;
spin_lock(&bdev_lock); spin_lock(&bdev_lock);
if (!bdev->bd_holder || bdev->bd_holder == holder) {
bdev->bd_holder = holder; /* first decide result */
if (bdev->bd_holder == holder)
res = 0; /* already a holder */
else if (bdev->bd_holder != NULL)
res = -EBUSY; /* held by someone else */
else if (bdev->bd_contains == bdev)
res = 0; /* 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
res = 0; /* is a partition of an un-held device */
/* now impose change */
if (res==0) {
/* 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;
bdev->bd_holders++; bdev->bd_holders++;
res = 0; bdev->bd_holder = holder;
} }
spin_unlock(&bdev_lock); spin_unlock(&bdev_lock);
return res; return res;
...@@ -433,6 +455,8 @@ int bd_claim(struct block_device *bdev, void *holder) ...@@ -433,6 +455,8 @@ int bd_claim(struct block_device *bdev, void *holder)
void bd_release(struct block_device *bdev) void bd_release(struct block_device *bdev)
{ {
spin_lock(&bdev_lock); spin_lock(&bdev_lock);
if (!--bdev->bd_contains->bd_holders)
bdev->bd_contains->bd_holder = NULL;
if (!--bdev->bd_holders) if (!--bdev->bd_holders)
bdev->bd_holder = NULL; bdev->bd_holder = NULL;
spin_unlock(&bdev_lock); spin_unlock(&bdev_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment