/proc/sys/vm/block_dump


/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して検証されたらと思います。


最終更新 2014/10/31 18:43:42 - north
(2014/10/31 18:43:42 作成)


検索

アクセス数
3570026
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。