aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/block_dev.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 2a6d0193f139..e59440c7e1cf 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -661,41 +661,70 @@ void bd_forget(struct inode *inode)
661 iput(bdev->bd_inode); 661 iput(bdev->bd_inode);
662} 662}
663 663
664int bd_claim(struct block_device *bdev, void *holder) 664/**
665 * bd_may_claim - test whether a block device can be claimed
666 * @bdev: block device of interest
667 * @whole: whole block device containing @bdev, may equal @bdev
668 * @holder: holder trying to claim @bdev
669 *
670 * Test whther @bdev can be claimed by @holder.
671 *
672 * CONTEXT:
673 * spin_lock(&bdev_lock).
674 *
675 * RETURNS:
676 * %true if @bdev can be claimed, %false otherwise.
677 */
678static bool bd_may_claim(struct block_device *bdev, struct block_device *whole,
679 void *holder)
665{ 680{
666 int res;
667 spin_lock(&bdev_lock);
668
669 /* first decide result */
670 if (bdev->bd_holder == holder) 681 if (bdev->bd_holder == holder)
671 res = 0; /* already a holder */ 682 return true; /* already a holder */
672 else if (bdev->bd_holder != NULL) 683 else if (bdev->bd_holder != NULL)
673 res = -EBUSY; /* held by someone else */ 684 return false; /* held by someone else */
674 else if (bdev->bd_contains == bdev) 685 else if (bdev->bd_contains == bdev)
675 res = 0; /* is a whole device which isn't held */ 686 return true; /* is a whole device which isn't held */
676 687
677 else if (bdev->bd_contains->bd_holder == bd_claim) 688 else if (whole->bd_holder == bd_claim)
678 res = 0; /* is a partition of a device that is being partitioned */ 689 return true; /* is a partition of a device that is being partitioned */
679 else if (bdev->bd_contains->bd_holder != NULL) 690 else if (whole->bd_holder != NULL)
680 res = -EBUSY; /* is a partition of a held device */ 691 return false; /* is a partition of a held device */
681 else 692 else
682 res = 0; /* is a partition of an un-held device */ 693 return true; /* is a partition of an un-held device */
694}
683 695
684 /* now impose change */ 696/**
685 if (res==0) { 697 * bd_claim - claim a block device
698 * @bdev: block device to claim
699 * @holder: holder trying to claim @bdev
700 *
701 * Try to claim @bdev.
702 *
703 * RETURNS:
704 * 0 if successful, -EBUSY if @bdev is already claimed.
705 */
706int bd_claim(struct block_device *bdev, void *holder)
707{
708 struct block_device *whole = bdev->bd_contains;
709 int res = -EBUSY;
710
711 spin_lock(&bdev_lock);
712
713 if (bd_may_claim(bdev, whole, holder)) {
686 /* note that for a whole device bd_holders 714 /* note that for a whole device bd_holders
687 * will be incremented twice, and bd_holder will 715 * will be incremented twice, and bd_holder will
688 * be set to bd_claim before being set to holder 716 * be set to bd_claim before being set to holder
689 */ 717 */
690 bdev->bd_contains->bd_holders ++; 718 whole->bd_holders++;
691 bdev->bd_contains->bd_holder = bd_claim; 719 whole->bd_holder = bd_claim;
692 bdev->bd_holders++; 720 bdev->bd_holders++;
693 bdev->bd_holder = holder; 721 bdev->bd_holder = holder;
722 res = 0;
694 } 723 }
724
695 spin_unlock(&bdev_lock); 725 spin_unlock(&bdev_lock);
696 return res; 726 return res;
697} 727}
698
699EXPORT_SYMBOL(bd_claim); 728EXPORT_SYMBOL(bd_claim);
700 729
701void bd_release(struct block_device *bdev) 730void bd_release(struct block_device *bdev)