Linux那些事儿之我是Block层(5)浓缩就是精华?(二) – fudan

1103 /*

1104 * bd_mutex locking:

1105 *

1106 * mutex_lock(part->bd_mutex)

1107 * mutex_lock_nested(whole->bd_mutex, 1)

1108 */

1109

1110 static int do_open(struct block_device *bdev, struct file *file, int for_part)

1111 {

1112 struct module *owner = NULL;

1113 struct gendisk *disk;

1114 int ret = -ENXIO;

1115 int part;

1116

1117 file->f_mapping = bdev->bd_inode->i_mapping;

1118 lock_kernel();

1119 disk = get_gendisk(bdev->bd_dev, &part);

1120 if (!disk) {

1121 unlock_kernel();

1122 bdput(bdev);

1123 return ret;

1124 }

1125 owner = disk->fops->owner;

1126

1127 mutex_lock_nested(&bdev->bd_mutex, for_part);

1128 if (!bdev->bd_openers) {

1129 bdev->bd_disk = disk;

1130 bdev->bd_contains = bdev;

1131 if (!part) {

1132 struct backing_dev_info *bdi;

1133 if (disk->fops->open) {

1134 ret = disk->fops->open(bdev->bd_inode, file);

1135 if (ret)

1136 goto out_first;

1137 }

1138 if (!bdev->bd_openers) {

1139 bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);

1140 bdi = blk_get_backing_dev_info(bdev);

1141 if (bdi == NULL)

1142 bdi = &default_backing_dev_info;

1143 bdev->bd_inode->i_data.backing_dev_info = bdi;

1144 }

1145 if (bdev->bd_invalidated)

1146 rescan_partitions(disk, bdev);

1147 } else {

1148 struct hd_struct *p;

1149 struct block_device *whole;

1150 whole = bdget_disk(disk, 0);

1151 ret = -ENOMEM;

1152 if (!whole)

1153 goto out_first;

1154 BUG_ON(for_part);

1155 ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1);

1156 if (ret)

1157 goto out_first;

1158 bdev->bd_contains = whole;

1159 p = disk->part[part – 1];

1160 bdev->bd_inode->i_data.backing_dev_info =

1161 whole->bd_inode->i_data.backing_dev_info;

1162 if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) {

1163 ret = -ENXIO;

1164 goto out_first;

1165 }

1166 kobject_get(&p->kobj);

1167 bdev->bd_part = p;

1168 bd_set_size(bdev, (loff_t) p->nr_sects << 9);

1169 }

1170 } else {

1171 put_disk(disk);

1172 module_put(owner);

1173 if (bdev->bd_contains == bdev) {

1174 if (bdev->bd_disk->fops->open) {

1175 ret = bdev->bd_disk->fops->open(bdev->bd_inode, file);

1176 if (ret)

1177 goto out;

1178 }

1179 if (bdev->bd_invalidated)

1180 rescan_partitions(bdev->bd_disk, bdev);

1181 }

1182 }

1183 bdev->bd_openers++;

1184 if (for_part)

1185 bdev->bd_part_count++;

1186 mutex_unlock(&bdev->bd_mutex);

1187 unlock_kernel();

1188 return 0;

1189

1190 out_first:

1191 bdev->bd_disk = NULL;

1192 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;

1193 if (bdev != bdev->bd_contains)

1194 __blkdev_put(bdev->bd_contains, 1);

1195 bdev->bd_contains = NULL;

1196 put_disk(disk);

1197 module_put(owner);

1198 out:

1199 mutex_unlock(&bdev->bd_mutex);

1200 unlock_kernel();

1201 if (ret)

1202 bdput(bdev);

1203 return ret;

1204 }

爬上那座山,听最圣洁的经。

Linux那些事儿之我是Block层(5)浓缩就是精华?(二) – fudan

相关文章:

你感兴趣的文章:

标签云: