#define UTS_RELEASE "2.6.35.7-perf"
/kernel/fs/block_dev.c
const struct file_operations def_blk_fops = {
.open = blkdev_open,
...
};
static int blkdev_open(struct inode * inode, struct file * filp)
{......
1487 bdev = bd_acquire(inode);------------------------------------->acquire the block device.
1488 if (bdev == NULL)}
blkdev_get------->__blkdev_get()
static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
{
......
restart:
ret = -ENXIO;
disk = get_gendisk(bdev->bd_dev, &partno);------------------->get partitioning information for a given device
if (!disk)
goto out_unlock_kernel;
mutex_lock_nested(&bdev->bd_mutex, for_part);
if (!bdev->bd_openers) {---------------------------------------------->block device is opened before?
bdev->bd_disk = disk;
bdev->bd_contains = bdev;
if (!partno) {------------------------------------------------------------>is partition?
struct backing_dev_info *bdi;
ret = -ENXIO;
bdev->bd_part = disk_get_part(disk, partno);------------>get the hd_struct
if (!bdev->bd_part)
goto out_clear;
if (disk->fops->open) {------------------------------------------->is open is defined in fops?
ret = disk->fops->open(bdev, mode);-------------------->do the open operation of fops
if (ret == -ERESTARTSYS) {
/* Lost a race with 'disk' being
* deleted, try again.
* See md.c
*/
disk_put_part(bdev->bd_part);
bdev->bd_part = NULL;
module_put(disk->fops->owner);
put_disk(disk);
bdev->bd_disk = NULL;
mutex_unlock(&bdev->bd_mutex);
goto restart;
}
if (ret)
goto out_clear;
}
if (!bdev->bd_openers) {
bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
bdi = blk_get_backing_dev_info(bdev);
if (bdi == NULL)
bdi = &default_backing_dev_info;
bdev->bd_inode->i_data.backing_dev_info = bdi;
}
if (bdev->bd_invalidated)-------------------------------------------->partition information is validate?
rescan_partitions(disk, bdev);-------------------------------------------->partition information is validate?
} else {----------------------------------------------------------------------->is partition, then insert the block_device in to data struct.
struct block_device *whole;
whole = bdget_disk(disk, 0);
ret = -ENOMEM;
if (!whole)
goto out_clear;
BUG_ON(for_part);
ret = __blkdev_get(whole, mode, 1);
if (ret)
goto out_clear;
bdev->bd_contains = whole;
bdev->bd_inode->i_data.backing_dev_info =
whole->bd_inode->i_data.backing_dev_info;
bdev->bd_part = disk_get_part(disk, partno);
if (!(disk->flags & GENHD_FL_UP) ||
!bdev->bd_part || !bdev->bd_part->nr_sects) {
ret = -ENXIO;
goto out_clear;
}
bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
}
} else {----------------------------------------------------------------------------------->opened before
module_put(disk->fops->owner);
put_disk(disk);
disk = NULL;
if (bdev->bd_contains == bdev) {--------------------------------------------->is main device
if (bdev->bd_disk->fops->open) {----------------------------------------->do open operation
ret = bdev->bd_disk->fops->open(bdev, mode);
if (ret)
goto out_unlock_bdev;
}
if (bdev->bd_invalidated)------------------------------------------------------>partition information is validate?
rescan_partitions(bdev->bd_disk, bdev);----------------------------->partition information is validate?
}
}
bdev->bd_openers++;
if (for_part)
bdev->bd_part_count++;
mutex_unlock(&bdev->bd_mutex);
unlock_kernel();
return 0;
......
}