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.c218
1 files changed, 148 insertions, 70 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 028d9fb9c2d5..4346468139e8 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -5,14 +5,12 @@
5 * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE 5 * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/init.h> 8#include <linux/init.h>
10#include <linux/mm.h> 9#include <linux/mm.h>
11#include <linux/fcntl.h> 10#include <linux/fcntl.h>
12#include <linux/slab.h> 11#include <linux/slab.h>
13#include <linux/kmod.h> 12#include <linux/kmod.h>
14#include <linux/major.h> 13#include <linux/major.h>
15#include <linux/devfs_fs_kernel.h>
16#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
17#include <linux/highmem.h> 15#include <linux/highmem.h>
18#include <linux/blkdev.h> 16#include <linux/blkdev.h>
@@ -545,11 +543,11 @@ static struct kobject *bdev_get_holder(struct block_device *bdev)
545 return kobject_get(bdev->bd_disk->holder_dir); 543 return kobject_get(bdev->bd_disk->holder_dir);
546} 544}
547 545
548static void add_symlink(struct kobject *from, struct kobject *to) 546static int add_symlink(struct kobject *from, struct kobject *to)
549{ 547{
550 if (!from || !to) 548 if (!from || !to)
551 return; 549 return 0;
552 sysfs_create_link(from, to, kobject_name(to)); 550 return sysfs_create_link(from, to, kobject_name(to));
553} 551}
554 552
555static void del_symlink(struct kobject *from, struct kobject *to) 553static void del_symlink(struct kobject *from, struct kobject *to)
@@ -650,30 +648,38 @@ static void free_bd_holder(struct bd_holder *bo)
650 * If there is no matching entry with @bo in @bdev->bd_holder_list, 648 * If there is no matching entry with @bo in @bdev->bd_holder_list,
651 * add @bo to the list, create symlinks. 649 * add @bo to the list, create symlinks.
652 * 650 *
653 * Returns 1 if @bo was added to the list. 651 * Returns 0 if symlinks are created or already there.
654 * Returns 0 if @bo wasn't used by any reason and should be freed. 652 * Returns -ve if something fails and @bo can be freed.
655 */ 653 */
656static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) 654static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
657{ 655{
658 struct bd_holder *tmp; 656 struct bd_holder *tmp;
657 int ret;
659 658
660 if (!bo) 659 if (!bo)
661 return 0; 660 return -EINVAL;
662 661
663 list_for_each_entry(tmp, &bdev->bd_holder_list, list) { 662 list_for_each_entry(tmp, &bdev->bd_holder_list, list) {
664 if (tmp->sdir == bo->sdir) { 663 if (tmp->sdir == bo->sdir) {
665 tmp->count++; 664 tmp->count++;
665 /* We've already done what we need to do here. */
666 free_bd_holder(bo);
666 return 0; 667 return 0;
667 } 668 }
668 } 669 }
669 670
670 if (!bd_holder_grab_dirs(bdev, bo)) 671 if (!bd_holder_grab_dirs(bdev, bo))
671 return 0; 672 return -EBUSY;
672 673
673 add_symlink(bo->sdir, bo->sdev); 674 ret = add_symlink(bo->sdir, bo->sdev);
674 add_symlink(bo->hdir, bo->hdev); 675 if (ret == 0) {
675 list_add_tail(&bo->list, &bdev->bd_holder_list); 676 ret = add_symlink(bo->hdir, bo->hdev);
676 return 1; 677 if (ret)
678 del_symlink(bo->sdir, bo->sdev);
679 }
680 if (ret == 0)
681 list_add_tail(&bo->list, &bdev->bd_holder_list);
682 return ret;
677} 683}
678 684
679/** 685/**
@@ -741,9 +747,11 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
741 if (!bo) 747 if (!bo)
742 return -ENOMEM; 748 return -ENOMEM;
743 749
744 mutex_lock(&bdev->bd_mutex); 750 mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
745 res = bd_claim(bdev, holder); 751 res = bd_claim(bdev, holder);
746 if (res || !add_bd_holder(bdev, bo)) 752 if (res == 0)
753 res = add_bd_holder(bdev, bo);
754 if (res)
747 free_bd_holder(bo); 755 free_bd_holder(bo);
748 mutex_unlock(&bdev->bd_mutex); 756 mutex_unlock(&bdev->bd_mutex);
749 757
@@ -766,7 +774,7 @@ static void bd_release_from_kobject(struct block_device *bdev,
766 if (!kobj) 774 if (!kobj)
767 return; 775 return;
768 776
769 mutex_lock(&bdev->bd_mutex); 777 mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
770 bd_release(bdev); 778 bd_release(bdev);
771 if ((bo = del_bd_holder(bdev, kobj))) 779 if ((bo = del_bd_holder(bdev, kobj)))
772 free_bd_holder(bo); 780 free_bd_holder(bo);
@@ -824,6 +832,22 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode)
824 832
825EXPORT_SYMBOL(open_by_devnum); 833EXPORT_SYMBOL(open_by_devnum);
826 834
835static int
836blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags);
837
838struct block_device *open_partition_by_devnum(dev_t dev, unsigned mode)
839{
840 struct block_device *bdev = bdget(dev);
841 int err = -ENOMEM;
842 int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY;
843 if (bdev)
844 err = blkdev_get_partition(bdev, mode, flags);
845 return err ? ERR_PTR(err) : bdev;
846}
847
848EXPORT_SYMBOL(open_partition_by_devnum);
849
850
827/* 851/*
828 * This routine checks whether a removable media has been changed, 852 * This routine checks whether a removable media has been changed,
829 * and invalidates all buffer-cache-entries in that case. This 853 * and invalidates all buffer-cache-entries in that case. This
@@ -870,7 +894,66 @@ void bd_set_size(struct block_device *bdev, loff_t size)
870} 894}
871EXPORT_SYMBOL(bd_set_size); 895EXPORT_SYMBOL(bd_set_size);
872 896
873static int do_open(struct block_device *bdev, struct file *file) 897static int __blkdev_put(struct block_device *bdev, unsigned int subclass)
898{
899 int ret = 0;
900 struct inode *bd_inode = bdev->bd_inode;
901 struct gendisk *disk = bdev->bd_disk;
902
903 mutex_lock_nested(&bdev->bd_mutex, subclass);
904 lock_kernel();
905 if (!--bdev->bd_openers) {
906 sync_blockdev(bdev);
907 kill_bdev(bdev);
908 }
909 if (bdev->bd_contains == bdev) {
910 if (disk->fops->release)
911 ret = disk->fops->release(bd_inode, NULL);
912 } else {
913 mutex_lock_nested(&bdev->bd_contains->bd_mutex,
914 subclass + 1);
915 bdev->bd_contains->bd_part_count--;
916 mutex_unlock(&bdev->bd_contains->bd_mutex);
917 }
918 if (!bdev->bd_openers) {
919 struct module *owner = disk->fops->owner;
920
921 put_disk(disk);
922 module_put(owner);
923
924 if (bdev->bd_contains != bdev) {
925 kobject_put(&bdev->bd_part->kobj);
926 bdev->bd_part = NULL;
927 }
928 bdev->bd_disk = NULL;
929 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
930 if (bdev != bdev->bd_contains)
931 __blkdev_put(bdev->bd_contains, subclass + 1);
932 bdev->bd_contains = NULL;
933 }
934 unlock_kernel();
935 mutex_unlock(&bdev->bd_mutex);
936 bdput(bdev);
937 return ret;
938}
939
940int blkdev_put(struct block_device *bdev)
941{
942 return __blkdev_put(bdev, BD_MUTEX_NORMAL);
943}
944EXPORT_SYMBOL(blkdev_put);
945
946int blkdev_put_partition(struct block_device *bdev)
947{
948 return __blkdev_put(bdev, BD_MUTEX_PARTITION);
949}
950EXPORT_SYMBOL(blkdev_put_partition);
951
952static int
953blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags);
954
955static int
956do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
874{ 957{
875 struct module *owner = NULL; 958 struct module *owner = NULL;
876 struct gendisk *disk; 959 struct gendisk *disk;
@@ -887,7 +970,8 @@ static int do_open(struct block_device *bdev, struct file *file)
887 } 970 }
888 owner = disk->fops->owner; 971 owner = disk->fops->owner;
889 972
890 mutex_lock(&bdev->bd_mutex); 973 mutex_lock_nested(&bdev->bd_mutex, subclass);
974
891 if (!bdev->bd_openers) { 975 if (!bdev->bd_openers) {
892 bdev->bd_disk = disk; 976 bdev->bd_disk = disk;
893 bdev->bd_contains = bdev; 977 bdev->bd_contains = bdev;
@@ -914,11 +998,11 @@ static int do_open(struct block_device *bdev, struct file *file)
914 ret = -ENOMEM; 998 ret = -ENOMEM;
915 if (!whole) 999 if (!whole)
916 goto out_first; 1000 goto out_first;
917 ret = blkdev_get(whole, file->f_mode, file->f_flags); 1001 ret = blkdev_get_whole(whole, file->f_mode, file->f_flags);
918 if (ret) 1002 if (ret)
919 goto out_first; 1003 goto out_first;
920 bdev->bd_contains = whole; 1004 bdev->bd_contains = whole;
921 mutex_lock(&whole->bd_mutex); 1005 mutex_lock_nested(&whole->bd_mutex, BD_MUTEX_WHOLE);
922 whole->bd_part_count++; 1006 whole->bd_part_count++;
923 p = disk->part[part - 1]; 1007 p = disk->part[part - 1];
924 bdev->bd_inode->i_data.backing_dev_info = 1008 bdev->bd_inode->i_data.backing_dev_info =
@@ -946,7 +1030,8 @@ static int do_open(struct block_device *bdev, struct file *file)
946 if (bdev->bd_invalidated) 1030 if (bdev->bd_invalidated)
947 rescan_partitions(bdev->bd_disk, bdev); 1031 rescan_partitions(bdev->bd_disk, bdev);
948 } else { 1032 } else {
949 mutex_lock(&bdev->bd_contains->bd_mutex); 1033 mutex_lock_nested(&bdev->bd_contains->bd_mutex,
1034 BD_MUTEX_WHOLE);
950 bdev->bd_contains->bd_part_count++; 1035 bdev->bd_contains->bd_part_count++;
951 mutex_unlock(&bdev->bd_contains->bd_mutex); 1036 mutex_unlock(&bdev->bd_contains->bd_mutex);
952 } 1037 }
@@ -960,7 +1045,7 @@ out_first:
960 bdev->bd_disk = NULL; 1045 bdev->bd_disk = NULL;
961 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; 1046 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
962 if (bdev != bdev->bd_contains) 1047 if (bdev != bdev->bd_contains)
963 blkdev_put(bdev->bd_contains); 1048 __blkdev_put(bdev->bd_contains, BD_MUTEX_WHOLE);
964 bdev->bd_contains = NULL; 1049 bdev->bd_contains = NULL;
965 put_disk(disk); 1050 put_disk(disk);
966 module_put(owner); 1051 module_put(owner);
@@ -987,11 +1072,49 @@ int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags)
987 fake_file.f_dentry = &fake_dentry; 1072 fake_file.f_dentry = &fake_dentry;
988 fake_dentry.d_inode = bdev->bd_inode; 1073 fake_dentry.d_inode = bdev->bd_inode;
989 1074
990 return do_open(bdev, &fake_file); 1075 return do_open(bdev, &fake_file, BD_MUTEX_NORMAL);
991} 1076}
992 1077
993EXPORT_SYMBOL(blkdev_get); 1078EXPORT_SYMBOL(blkdev_get);
994 1079
1080static int
1081blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags)
1082{
1083 /*
1084 * This crockload is due to bad choice of ->open() type.
1085 * It will go away.
1086 * For now, block device ->open() routine must _not_
1087 * examine anything in 'inode' argument except ->i_rdev.
1088 */
1089 struct file fake_file = {};
1090 struct dentry fake_dentry = {};
1091 fake_file.f_mode = mode;
1092 fake_file.f_flags = flags;
1093 fake_file.f_dentry = &fake_dentry;
1094 fake_dentry.d_inode = bdev->bd_inode;
1095
1096 return do_open(bdev, &fake_file, BD_MUTEX_WHOLE);
1097}
1098
1099static int
1100blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags)
1101{
1102 /*
1103 * This crockload is due to bad choice of ->open() type.
1104 * It will go away.
1105 * For now, block device ->open() routine must _not_
1106 * examine anything in 'inode' argument except ->i_rdev.
1107 */
1108 struct file fake_file = {};
1109 struct dentry fake_dentry = {};
1110 fake_file.f_mode = mode;
1111 fake_file.f_flags = flags;
1112 fake_file.f_dentry = &fake_dentry;
1113 fake_dentry.d_inode = bdev->bd_inode;
1114
1115 return do_open(bdev, &fake_file, BD_MUTEX_PARTITION);
1116}
1117
995static int blkdev_open(struct inode * inode, struct file * filp) 1118static int blkdev_open(struct inode * inode, struct file * filp)
996{ 1119{
997 struct block_device *bdev; 1120 struct block_device *bdev;
@@ -1007,7 +1130,7 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1007 1130
1008 bdev = bd_acquire(inode); 1131 bdev = bd_acquire(inode);
1009 1132
1010 res = do_open(bdev, filp); 1133 res = do_open(bdev, filp, BD_MUTEX_NORMAL);
1011 if (res) 1134 if (res)
1012 return res; 1135 return res;
1013 1136
@@ -1021,51 +1144,6 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1021 return res; 1144 return res;
1022} 1145}
1023 1146
1024int blkdev_put(struct block_device *bdev)
1025{
1026 int ret = 0;
1027 struct inode *bd_inode = bdev->bd_inode;
1028 struct gendisk *disk = bdev->bd_disk;
1029
1030 mutex_lock(&bdev->bd_mutex);
1031 lock_kernel();
1032 if (!--bdev->bd_openers) {
1033 sync_blockdev(bdev);
1034 kill_bdev(bdev);
1035 }
1036 if (bdev->bd_contains == bdev) {
1037 if (disk->fops->release)
1038 ret = disk->fops->release(bd_inode, NULL);
1039 } else {
1040 mutex_lock(&bdev->bd_contains->bd_mutex);
1041 bdev->bd_contains->bd_part_count--;
1042 mutex_unlock(&bdev->bd_contains->bd_mutex);
1043 }
1044 if (!bdev->bd_openers) {
1045 struct module *owner = disk->fops->owner;
1046
1047 put_disk(disk);
1048 module_put(owner);
1049
1050 if (bdev->bd_contains != bdev) {
1051 kobject_put(&bdev->bd_part->kobj);
1052 bdev->bd_part = NULL;
1053 }
1054 bdev->bd_disk = NULL;
1055 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
1056 if (bdev != bdev->bd_contains) {
1057 blkdev_put(bdev->bd_contains);
1058 }
1059 bdev->bd_contains = NULL;
1060 }
1061 unlock_kernel();
1062 mutex_unlock(&bdev->bd_mutex);
1063 bdput(bdev);
1064 return ret;
1065}
1066
1067EXPORT_SYMBOL(blkdev_put);
1068
1069static int blkdev_close(struct inode * inode, struct file * filp) 1147static int blkdev_close(struct inode * inode, struct file * filp)
1070{ 1148{
1071 struct block_device *bdev = I_BDEV(filp->f_mapping->host); 1149 struct block_device *bdev = I_BDEV(filp->f_mapping->host);
@@ -1095,7 +1173,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1095 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); 1173 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
1096} 1174}
1097 1175
1098struct address_space_operations def_blk_aops = { 1176const struct address_space_operations def_blk_aops = {
1099 .readpage = blkdev_readpage, 1177 .readpage = blkdev_readpage,
1100 .writepage = blkdev_writepage, 1178 .writepage = blkdev_writepage,
1101 .sync_page = block_sync_page, 1179 .sync_page = block_sync_page,