I have a couple of general questions regarding the Linux page cache. As I understand, there are (at least) three methods a block on a block device can be related to a block buffer in page cache:
- by the disk device file, e.g.,
/dev/sda
- by the partition device file, e.g.,
/dev/sda1
- by a regular file, e.g.,
/home/me/hello
suppose the /dev/sda1
contains an typical linux filesystem, such as ext2, which is mounted on /
and /home
folder is in this filesystem.
And the three methods have different page caches since their address_space
object are embedded in different inode
objects:
bdev
special filesystem'sinode
, for/dev/sda
bdev
special filesystem'sinode
, for/dev/sda1
ext2
filesystem'sinode
, for/home/me/hello
Now here are the questions:
I thought
super_block
object is only allocated for a mounted filesystem, and sincebdev
is not really mounted anywhere, there is nosuper_block
object for it. Therefore whenwriteback_inodes()
loops oversuper_block
objects and search for dirtyinode
, page caches from method 1 & 2 above will be missed, hence they require manual sync to disk?Is it possible that a user can read/write a block on disk that belongs to file
/home/me/hello
in all three methods listed above, hence make the contents in the three page caches out of sync? I can see in kernel 2.6.11 code there is effort when writing a file in method 3, it waits for a device cache to sync and then proceed, although this device could be either disk device(method 1) or partition device(method 2), but it couldn't be both. And I didn't find similar code in kernel 5.3:
Code to wait for device cache:
static int __block_prepare_write(struct inode *inode, struct page *page,
unsigned from, unsigned to, get_block_t *get_block)
{
...
unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
...
}
void unmap_underlying_metadata(struct block_device *bdev, sector_t block)
{
...
old_bh = __find_get_block_slow(bdev, block, 0);
if (old_bh) {
clear_buffer_dirty(old_bh);
wait_on_buffer(old_bh);
clear_buffer_req(old_bh);
__brelse(old_bh);
}
}
Still new to linux kernel hence the questions might not make much sense.. pointers appreciated!