Embeded linux 之 CIFS 文件操作源码分析

内核版本:3.18.20

一、文件操作:

  1.BDI写回机制:

    CIFS文件操作:也是基于文件的网络操作,所以依旧使用BDI写回机制。

    Linux内核的写回机制在 2.6.30之后的某个版本不再使用pdflush机制,使用一种新的BDI写回机制。

    现有的关于linux内核的书籍中,写回机制都是pdflush,而这种写回有一定的缺陷:多个写回进程可能阻塞在同一个块设备,导致其他块设备无法写回脏数据,因此就有了BDI写回机制的出现。

    BDI写回机制主要包含几个特点:

      •   每个块设备上有一个写回线程,写回线程的创建或终止由一个内核常驻线程控制;
      •   如果块设备在一定时间里一直没有写操作,那个该设备的写回线程被终止;

  2.与writeback相关的数据结构主要有:

      • backing_dev_info,该数据结构描述了backing_dev的所有信息,通常块设备的request queue中会包含backing_dev对象。
      • bdi_writeback,该数据结构封装了writeback的内核线程以及需要操作的inode队列。
      • wb_writeback_work,该数据结构封装了writeback的工作任务。

  3.bdi程序主流程

    int bdi_init(struct backing_dev_info *bdi)

    bdi_wb_init(&bdi->wb, bdi);

    INIT_DELAYED_WORK(&wb->dwork, bdi_writeback_workfn);//中断处理函数

    void bdi_writeback_workfn(struct work_struct *work)

    bdi_wakeup_thread_delayed(bdi);

    unsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */

    timeout = msecs_to_jiffies(dirty_writeback_interval * 10);

    queue_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);

    void bdi_writeback_workfn(struct work_struct *work)

    • do {
    • pages_written = wb_do_writeback(wb);
    • trace_writeback_pages_written(pages_written);
    • } while (!list_empty(&bdi->work_list));

    static long wb_writeback(struct bdi_writeback *wb,struct wb_writeback_work *work)

    • wrote += wb_check_old_data_flush(wb);//周期性的检查脏页并写回,它默认写回30s之前写入的脏页,每隔5s扫描一次。
    • wrote += wb_check_background_flush(wb);//脏页达到一定比例时写回所有的脏页,直到脏页的比例达到阀值以下
    • clear_bit(BDI_writeback_running, &wb->bdi->state);

    static long wb_check_old_data_flush(struct bdi_writeback *wb)

    {//......

      return wb_writeback(wb, &work);

     //......

    }

    static long wb_check_background_flush(struct bdi_writeback *wb)

    {//.....

      return wb_writeback(wb, &work);

     //.....

    }

    wb_writeback函数,该函数是Writeback机制中真正执行写回的函数。Writeback机制中的写回磁盘操作都是通过wb_writeback函数实现的,wb_writeback调用与文件系统有关的write函数,执行协会磁盘的操作。

  4.挂载cifs

    module_init(init_cifs)

    static int __init init_cifs(void)

    rc = register_filesystem(&cifs_fs_type);

    struct file_system_type cifs_fs_type = {
      .owner = THIS_MODULE,
      .name = "cifs",
      .mount = cifs_do_mount,
      .kill_sb = cifs_kill_sb,
      /* .fs_flags */
    };

    static struct dentry *cifs_do_mount(struct file_system_type *fs_type,int flags, const char *dev_name, void *data)    

    int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)

    rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);

    err = bdi_register(bdi, NULL, "%.28s-%ld", name, atomic_long_inc_return(&bdi_seq));//bdi_register函数用于注册后备存储器到全局链表bdi_list上,并且判断如果是默认的后备存储器default_backing_dev_info则创建bdi-default线程,用于管理创建或销毁所有后备存储器相关的同步回写线程。

    void bdi_writeback_workfn(struct work_struct *work)

  未完待续

    

原文地址:https://www.cnblogs.com/pokerface/p/7444120.html