aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c65
1 files changed, 33 insertions, 32 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index b3e9bfa748cf..2980eabe5779 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -517,7 +517,7 @@ void __init bdev_cache_init(void)
517 bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode), 517 bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode),
518 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| 518 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
519 SLAB_MEM_SPREAD|SLAB_PANIC), 519 SLAB_MEM_SPREAD|SLAB_PANIC),
520 init_once, NULL); 520 init_once);
521 err = register_filesystem(&bd_type); 521 err = register_filesystem(&bd_type);
522 if (err) 522 if (err)
523 panic("Cannot register bdev pseudo-fs"); 523 panic("Cannot register bdev pseudo-fs");
@@ -588,12 +588,10 @@ EXPORT_SYMBOL(bdget);
588 588
589long nr_blockdev_pages(void) 589long nr_blockdev_pages(void)
590{ 590{
591 struct list_head *p; 591 struct block_device *bdev;
592 long ret = 0; 592 long ret = 0;
593 spin_lock(&bdev_lock); 593 spin_lock(&bdev_lock);
594 list_for_each(p, &all_bdevs) { 594 list_for_each_entry(bdev, &all_bdevs, bd_list) {
595 struct block_device *bdev;
596 bdev = list_entry(p, struct block_device, bd_list);
597 ret += bdev->bd_inode->i_mapping->nrpages; 595 ret += bdev->bd_inode->i_mapping->nrpages;
598 } 596 }
599 spin_unlock(&bdev_lock); 597 spin_unlock(&bdev_lock);
@@ -874,7 +872,7 @@ static struct bd_holder *find_bd_holder(struct block_device *bdev,
874 */ 872 */
875static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) 873static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
876{ 874{
877 int ret; 875 int err;
878 876
879 if (!bo) 877 if (!bo)
880 return -EINVAL; 878 return -EINVAL;
@@ -882,15 +880,18 @@ static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
882 if (!bd_holder_grab_dirs(bdev, bo)) 880 if (!bd_holder_grab_dirs(bdev, bo))
883 return -EBUSY; 881 return -EBUSY;
884 882
885 ret = add_symlink(bo->sdir, bo->sdev); 883 err = add_symlink(bo->sdir, bo->sdev);
886 if (ret == 0) { 884 if (err)
887 ret = add_symlink(bo->hdir, bo->hdev); 885 return err;
888 if (ret) 886
889 del_symlink(bo->sdir, bo->sdev); 887 err = add_symlink(bo->hdir, bo->hdev);
888 if (err) {
889 del_symlink(bo->sdir, bo->sdev);
890 return err;
890 } 891 }
891 if (ret == 0) 892
892 list_add_tail(&bo->list, &bdev->bd_holder_list); 893 list_add_tail(&bo->list, &bdev->bd_holder_list);
893 return ret; 894 return 0;
894} 895}
895 896
896/** 897/**
@@ -948,7 +949,7 @@ static struct bd_holder *del_bd_holder(struct block_device *bdev,
948static int bd_claim_by_kobject(struct block_device *bdev, void *holder, 949static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
949 struct kobject *kobj) 950 struct kobject *kobj)
950{ 951{
951 int res; 952 int err;
952 struct bd_holder *bo, *found; 953 struct bd_holder *bo, *found;
953 954
954 if (!kobj) 955 if (!kobj)
@@ -959,21 +960,24 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
959 return -ENOMEM; 960 return -ENOMEM;
960 961
961 mutex_lock(&bdev->bd_mutex); 962 mutex_lock(&bdev->bd_mutex);
962 res = bd_claim(bdev, holder);
963 if (res == 0) {
964 found = find_bd_holder(bdev, bo);
965 if (found == NULL) {
966 res = add_bd_holder(bdev, bo);
967 if (res)
968 bd_release(bdev);
969 }
970 }
971 963
972 if (res || found) 964 err = bd_claim(bdev, holder);
973 free_bd_holder(bo); 965 if (err)
974 mutex_unlock(&bdev->bd_mutex); 966 goto fail;
975 967
976 return res; 968 found = find_bd_holder(bdev, bo);
969 if (found)
970 goto fail;
971
972 err = add_bd_holder(bdev, bo);
973 if (err)
974 bd_release(bdev);
975 else
976 bo = NULL;
977fail:
978 mutex_unlock(&bdev->bd_mutex);
979 free_bd_holder(bo);
980 return err;
977} 981}
978 982
979/** 983/**
@@ -987,15 +991,12 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
987static void bd_release_from_kobject(struct block_device *bdev, 991static void bd_release_from_kobject(struct block_device *bdev,
988 struct kobject *kobj) 992 struct kobject *kobj)
989{ 993{
990 struct bd_holder *bo;
991
992 if (!kobj) 994 if (!kobj)
993 return; 995 return;
994 996
995 mutex_lock(&bdev->bd_mutex); 997 mutex_lock(&bdev->bd_mutex);
996 bd_release(bdev); 998 bd_release(bdev);
997 if ((bo = del_bd_holder(bdev, kobj))) 999 free_bd_holder(del_bd_holder(bdev, kobj));
998 free_bd_holder(bo);
999 mutex_unlock(&bdev->bd_mutex); 1000 mutex_unlock(&bdev->bd_mutex);
1000} 1001}
1001 1002