/proc/sys/vm/block_dumpは、パブリック変数block_dumpを更新します。block_dump!=0だと、bioの入出力/inodeのdirtyを、カーネルログとして出力します。
検証結果です。/dev/sdc0はext2です。
[root@localhost lkm]# echo 1 > /proc/sys/vm/block_dump
[root@localhost lkm]# mount /dev/sdc0 /mnt4
[root@localhost lkm]# echo hoge > /mnt4/hoge.txt
[root@localhost lkm]# dmesg | grep sbd0
[ 6181.136832] bash(1785): READ block 10 on sbd0 (2 sectors)
[ 6181.137088] bash(1785): dirtied inode 12 (hoge.txt) on sbd0
[ 6181.137099] bash(1785): dirtied inode 12 (hoge.txt) on sbd0
[ 6184.016616] sync_supers(17): WRITE block 2 on sbd0 (2 sectors)
[ 6211.185818] flush-252:0(1890): WRITE block 4 on sbd0 (2 sectors)
[ 6211.185874] flush-252:0(1890): WRITE block 10 on sbd0 (2 sectors)
[ 6211.185889] flush-252:0(1890): WRITE block 12 on sbd0 (2 sectors)
[ 6211.185900] flush-252:0(1890): WRITE block 14 on sbd0 (2 sectors)
[ 6211.185914] flush-252:0(1890): WRITE block 28 on sbd0 (2 sectors)
[ 6211.186152] flush-252:0(1890): READ block 8 on sbd0 (2 sectors)
[ 6211.186431] flush-252:0(1890): WRITE block 56 on sbd0 (2 sectors)
[ 6214.017662] sync_supers(17): WRITE block 2 on sbd0 (2 sectors)
[ 6241.230564] flush-252:0(1890): WRITE block 4 on sbd0 (2 sectors)
[ 6241.230621] flush-252:0(1890): WRITE block 8 on sbd0 (2 sectors)
[ 6241.230636] flush-252:0(1890): WRITE block 14 on sbd0 (2 sectors)
submit_bioログフォーマット:プロセス名(プロセスID): WRITE/READ: 参照セクター位置: デバイス名: 参照セクタ数
void submit_bio(int rw, struct bio *bio)
{
int count = bio_sectors(bio);
bio->bi_rw |= rw;
if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
if (rw & WRITE) {
count_vm_events(PGPGOUT, count);
} else {
task_io_account_read(bio->bi_size);
count_vm_events(PGPGIN, count);
}
if (unlikely(block_dump)) {
char b[BDEVNAME_SIZE];
printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)\n",
current->comm, task_pid_nr(current),
(rw & WRITE) ? "WRITE" : "READ",
(unsigned long long)bio->bi_sector,
bdevname(bio->bi_bdev, b),
count);
}
}
generic_make_request(bio);
}
EXPORT_SYMBOL(submit_bio);
mark_inode_dirtyログフォーマット:プロセス名(プロセスID): WRITE/READ: inode番号: ファイル名: デバイス名
void __mark_inode_dirty(struct inode *inode, int flags)
{
struct super_block *sb = inode->i_sb;
struct backing_dev_info *bdi = NULL;
if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
if (sb->s_op->dirty_inode)
sb->s_op->dirty_inode(inode, flags);
}
smp_mb();
if ((inode->i_state & flags) == flags)
return;
if (unlikely(block_dump))
block_dump___mark_inode_dirty(inode);
spin_lock(&inode->i_lock);
if ((inode->i_state & flags) != flags) {
const int was_dirty = inode->i_state & I_DIRTY;
inode->i_state |= flags;
if (inode->i_state & I_SYNC)
goto out_unlock_inode;
if (!S_ISBLK(inode->i_mode)) {
if (inode_unhashed(inode))
goto out_unlock_inode;
}
if (inode->i_state & I_FREEING)
goto out_unlock_inode;
if (!was_dirty) {
bool wakeup_bdi = false;
bdi = inode_to_bdi(inode);
if (bdi_cap_writeback_dirty(bdi)) {
WARN(!test_bit(BDI_registered, &bdi->state),
"bdi-%s not registered\n", bdi->name);
if (!wb_has_dirty_io(&bdi->wb))
wakeup_bdi = true;
}
spin_unlock(&inode->i_lock);
spin_lock(&bdi->wb.list_lock);
inode->dirtied_when = jiffies;
list_move(&inode->i_wb_list, &bdi->wb.b_dirty);
spin_unlock(&bdi->wb.list_lock);
if (wakeup_bdi)
bdi_wakeup_thread_delayed(bdi);
return;
}
}
out_unlock_inode:
spin_unlock(&inode->i_lock);
}
EXPORT_SYMBOL(__mark_inode_dirty);
static noinline void block_dump___mark_inode_dirty(struct inode *inode)
{
if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) {
struct dentry *dentry;
const char *name = "?";
dentry = d_find_alias(inode);
if (dentry) {
spin_lock(&dentry->d_lock);
name = (const char *) dentry->d_name.name;
}
printk(KERN_DEBUG
"%s(%d): dirtied inode %lu (%s) on %s\n",
current->comm, task_pid_nr(current), inode->i_ino,
name, inode->i_sb->s_id);
if (dentry) {
spin_unlock(&dentry->d_lock);
dput(dentry);
}
}
}
__mark_inode_dirty()が2度コールされていることが分かります。新規にinodeを作成時のext2_new_inode()と、データ(hoge)を書き込んだ時(サイズが更新)とで処理かと思います。
echo hoge > hoge.txtとするだけですが、かなりのブロックが参照されています。hoge.txtのinodeだけでなく、/のinodeのデータブロックにhoge.txtのinode情報を書き込んだり、データブロックだけでなく、かかるinodeを管理するinodeビットマップ/inodeテーブル/とか、使用有無を管理するデータブロック等も更新しなければなりません。
[ 6181.136832] bash(1785): READ block 10 on sbd0 (2 sectors)で、bashがブロック10をsyncでreadしているようです。たぶん/mntのinodeを取得し、立て続けにhoge.txtのinodeを作成するためではと・・・ 後はカーネルスレッドのflushで、dirtyなpageをbioで書き出しています。
まあ、/proc/sys/vm/block_dumpとは、こういう物だということで、fsの構造を調べてみようとされる方は、かかるセクタをbreadして検証されたらと思います。