diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 65 |
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 | ||
589 | long nr_blockdev_pages(void) | 589 | long 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 | */ |
875 | static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) | 873 | static 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, | |||
948 | static int bd_claim_by_kobject(struct block_device *bdev, void *holder, | 949 | static 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; | ||
977 | fail: | ||
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, | |||
987 | static void bd_release_from_kobject(struct block_device *bdev, | 991 | static 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 | ||