linux文件系统(三) - 内核回写机制

将数据写到page cache

写文件的时候其实是通过文件系统写到page cache中,然后再由相应的线程在适当的时机将page cache中的数据写到磁盘中。

//fs/fat/file.c
const struct file_operations fat_file_operations = {
...
        .aio_write      = generic_file_aio_write,
...
};

//mm/filemap.c
generic_file_aio_write
    __generic_file_aio_write
        generic_file_buffered_write
            generic_perform_write
                a_ops->write_begin
                iov_iter_copy_from_user_atomic(page, i, offset, bytes)
                a_ops->write_end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

回写page cache到磁盘


通过sync系统调用将page cache写到磁盘中

//fs/fat/file.c
const struct file_operations fat_file_operations = {
...
        .fsync          = fat_file_fsync,
...
};

fat_file_fsync  
    generic_file_fsync
        sync_inode_metadata
            sync_inode
                writeback_single_inode
                    __writeback_single_inode
                        do_writepages
                            mapping->a_ops->writepages
                        write_inode
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

通过回写工作队列bdi_writeback将page cache写到磁盘中

//mm/backing_dev.c
bdi_init
    bdi_wb_init
        INIT_DELAYED_WORK(&wb->dwork, bdi_writeback_workfn);

//fs/fs-writeback.c
bdi_writeback_workfn
    wb_do_writeback
        wb_writeback
            writeback_sb_inodes
                __writeback_single_inode
                    do_writepages
                        mapping->a_ops->writepages
                    write_inode
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这里初始化的时候安装了回写wb->dwork,并且wb->dwork的回调函数和前面系统sync系统调用一样最终都会调用__writeback_single_inode来回写page cache。

blk_init_queue
    blk_init_queue_node
        blk_alloc_queue_node
            bdi_init(&q->backing_dev_info);
            setup_timer(&q->backing_dev_info.laptop_mode_wb_timer, laptop_mode_timer_fn, ...

//mm/page-writeback.c
laptop_mode_timer_fn
    bdi_start_writeback //fs/fs-writeback.c
       __bdi_start_writeback
           bdi_queue_work
               mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在blk_init_queue时会初始化一个timer,并且timer的回调函数是laptop_mode_timer_fn,他里面会通过bdi_queue_work来调度回写wb->dwork。这样这个回写wb->dwork就会不断的被这个timer定时的调度执行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值