diff options
author | Nick Piggin <npiggin@suse.de> | 2010-05-25 11:51:19 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-06-10 13:08:34 -0400 |
commit | b0018361c3f934858592cbbb5e1a4f318c2a70ed (patch) | |
tree | fa14b78331f2683838a3aee5a694ec37911c4ea3 | |
parent | cf3425707ed9ce0d5ebaba20bc3d22dd39e52f2f (diff) |
block: bd_start_claiming cleanup
I don't like the subtle multi-context code in bd_claim (ie. detects where it
has been called based on bd_claiming). It seems clearer to just require a new
function to finish a 2-part claim.
Also improve commentary in bd_start_claiming as to how it should
be used.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r-- | fs/block_dev.c | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 204a7632c511..a1642ef60197 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -706,8 +706,13 @@ retry: | |||
706 | * @bdev is about to be opened exclusively. Check @bdev can be opened | 706 | * @bdev is about to be opened exclusively. Check @bdev can be opened |
707 | * exclusively and mark that an exclusive open is in progress. Each | 707 | * exclusively and mark that an exclusive open is in progress. Each |
708 | * successful call to this function must be matched with a call to | 708 | * successful call to this function must be matched with a call to |
709 | * either bd_claim() or bd_abort_claiming(). If this function | 709 | * either bd_finish_claiming() or bd_abort_claiming() (which do not |
710 | * succeeds, the matching bd_claim() is guaranteed to succeed. | 710 | * fail). |
711 | * | ||
712 | * This function is used to gain exclusive access to the block device | ||
713 | * without actually causing other exclusive open attempts to fail. It | ||
714 | * should be used when the open sequence itself requires exclusive | ||
715 | * access but may subsequently fail. | ||
711 | * | 716 | * |
712 | * CONTEXT: | 717 | * CONTEXT: |
713 | * Might sleep. | 718 | * Might sleep. |
@@ -783,15 +788,47 @@ static void bd_abort_claiming(struct block_device *whole, void *holder) | |||
783 | __bd_abort_claiming(whole, holder); /* releases bdev_lock */ | 788 | __bd_abort_claiming(whole, holder); /* releases bdev_lock */ |
784 | } | 789 | } |
785 | 790 | ||
791 | /* increment holders when we have a legitimate claim. requires bdev_lock */ | ||
792 | static void __bd_claim(struct block_device *bdev, struct block_device *whole, | ||
793 | void *holder) | ||
794 | { | ||
795 | /* note that for a whole device bd_holders | ||
796 | * will be incremented twice, and bd_holder will | ||
797 | * be set to bd_claim before being set to holder | ||
798 | */ | ||
799 | whole->bd_holders++; | ||
800 | whole->bd_holder = bd_claim; | ||
801 | bdev->bd_holders++; | ||
802 | bdev->bd_holder = holder; | ||
803 | } | ||
804 | |||
805 | /** | ||
806 | * bd_finish_claiming - finish claiming a block device | ||
807 | * @bdev: block device of interest (passed to bd_start_claiming()) | ||
808 | * @whole: whole block device returned by bd_start_claiming() | ||
809 | * @holder: holder trying to claim @bdev | ||
810 | * | ||
811 | * Finish a claiming block started by bd_start_claiming(). | ||
812 | * | ||
813 | * CONTEXT: | ||
814 | * Grabs and releases bdev_lock. | ||
815 | */ | ||
816 | static void bd_finish_claiming(struct block_device *bdev, | ||
817 | struct block_device *whole, void *holder) | ||
818 | { | ||
819 | spin_lock(&bdev_lock); | ||
820 | BUG_ON(whole->bd_claiming != holder); | ||
821 | BUG_ON(!bd_may_claim(bdev, whole, holder)); | ||
822 | __bd_claim(bdev, whole, holder); | ||
823 | __bd_abort_claiming(whole, holder); /* not actually an abort */ | ||
824 | } | ||
825 | |||
786 | /** | 826 | /** |
787 | * bd_claim - claim a block device | 827 | * bd_claim - claim a block device |
788 | * @bdev: block device to claim | 828 | * @bdev: block device to claim |
789 | * @holder: holder trying to claim @bdev | 829 | * @holder: holder trying to claim @bdev |
790 | * | 830 | * |
791 | * Try to claim @bdev which must have been opened successfully. This | 831 | * Try to claim @bdev which must have been opened successfully. |
792 | * function may be called with or without preceding | ||
793 | * blk_start_claiming(). In the former case, this function is always | ||
794 | * successful and terminates the claiming block. | ||
795 | * | 832 | * |
796 | * CONTEXT: | 833 | * CONTEXT: |
797 | * Might sleep. | 834 | * Might sleep. |
@@ -807,23 +844,10 @@ int bd_claim(struct block_device *bdev, void *holder) | |||
807 | might_sleep(); | 844 | might_sleep(); |
808 | 845 | ||
809 | spin_lock(&bdev_lock); | 846 | spin_lock(&bdev_lock); |
810 | |||
811 | res = bd_prepare_to_claim(bdev, whole, holder); | 847 | res = bd_prepare_to_claim(bdev, whole, holder); |
812 | if (res == 0) { | 848 | if (res == 0) |
813 | /* note that for a whole device bd_holders | 849 | __bd_claim(bdev, whole, holder); |
814 | * will be incremented twice, and bd_holder will | 850 | spin_unlock(&bdev_lock); |
815 | * be set to bd_claim before being set to holder | ||
816 | */ | ||
817 | whole->bd_holders++; | ||
818 | whole->bd_holder = bd_claim; | ||
819 | bdev->bd_holders++; | ||
820 | bdev->bd_holder = holder; | ||
821 | } | ||
822 | |||
823 | if (whole->bd_claiming) | ||
824 | __bd_abort_claiming(whole, holder); /* releases bdev_lock */ | ||
825 | else | ||
826 | spin_unlock(&bdev_lock); | ||
827 | 851 | ||
828 | return res; | 852 | return res; |
829 | } | 853 | } |
@@ -1477,7 +1501,7 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1477 | 1501 | ||
1478 | if (whole) { | 1502 | if (whole) { |
1479 | if (res == 0) | 1503 | if (res == 0) |
1480 | BUG_ON(bd_claim(bdev, filp) != 0); | 1504 | bd_finish_claiming(bdev, whole, filp); |
1481 | else | 1505 | else |
1482 | bd_abort_claiming(whole, filp); | 1506 | bd_abort_claiming(whole, filp); |
1483 | } | 1507 | } |
@@ -1713,7 +1737,7 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h | |||
1713 | if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) | 1737 | if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) |
1714 | goto out_blkdev_put; | 1738 | goto out_blkdev_put; |
1715 | 1739 | ||
1716 | BUG_ON(bd_claim(bdev, holder) != 0); | 1740 | bd_finish_claiming(bdev, whole, holder); |
1717 | return bdev; | 1741 | return bdev; |
1718 | 1742 | ||
1719 | out_blkdev_put: | 1743 | out_blkdev_put: |