Standard Operations for Block Devices

Block devices conform to a much more uniform scheme. This allows the kernel to provide a much larger selection of operations right from the start. These are grouped together in a general structure called blk_fops.

fs/block_dev.c const struct file_operations def_blk_fops = { .open = blkdev_open,

.release = blkdev_close,

.llseek = block_llseek,

.write = do_sync_write,

.aio_read = generic_file_aio_read,

.aio_write = generic_file_aio_write_nolock,

.mmap = generic_file_mmap,

.fsync = block_fsync,

.unlocked_ioctl = block_ioctl, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write,

Read and write operations are performed by generic kernel routines. The caches generally present in the kernel are used automatically for block devices.

file_operations must not be used with block_device_operations although both are similarly structured. Although file_operations is used by the VFS layer to communicate with userspace, the routines it contains invoke the functions in block_device_operations to implement communication with the block device. The block_device_operations must be implemented specifically for each block device to abstract the device properties, but the same file_operations that build on these can be used for all block devices.

In contrast to character devices, block devices are not fully described by the above data structures, because access to block devices is not performed in response to each individual request but is efficiently managed by a refined and complex system of caches and request lists. The caches are operated predominantly by general kernel code, but the request lists are managed by the block device layer. When I discuss possible block device driver operations at greater length, you will see further structures used to manage the request queue, which collects and arranges statements addressed to the relevant device.

Continue reading here: Representing Character Devices

Was this article helpful?

0 0