浅尝辄止69-FAT32-内核10

内存只是暂时的,磁盘才能长长久久。

标记内存为脏

内存里的文件终究要刷到磁盘上的,在write的时候没有刷,什么时候刷呢?
再看一下generic_perform_write,后面有一个a_ops->write_end调用。这个a_opsstruct address_space的一个成员,每个文件也有这么一个结构体,简单理解就是,这个结构体有磁盘空间与内存空间映射的信息。

ssize_t generic_perform_write(struct file *file,
                struct iov_iter *i, loff_t pos)
{
    struct address_space *mapping = file->f_mapping;
    const struct address_space_operations *a_ops = mapping->a_ops;
    //...
    copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
    //...
    status = a_ops->write_end(file, mapping, pos, bytes, copied,
                        page, fsdata);
    //...
}

对于FAT,a_ops就是fat_aops[kernel/fs/fat/inode.c],a_ops->write_end就是fat_write_end

static const struct address_space_operations fat_aops = {
    .readpage   = fat_readpage,
    .readpages  = fat_readpages,
    .writepage  = fat_writepage,
    .writepages = fat_writepages,
    .write_begin    = fat_write_begin,
    .write_end  = fat_write_end,
    .direct_IO  = fat_direct_IO,
    .bmap       = _fat_bmap
};

再到fat_write_end==>block_write_end[kernel/fs/buffer.c]==>__block_commit_write可以发现,这里有mark_buffer_dirty,它会把扇区对应的内存标记为脏。

static int __block_commit_write(struct inode *inode, struct page *page,
        unsigned from, unsigned to)
{
    unsigned block_start, block_end;
    int partial = 0;
    unsigned blocksize;
    struct buffer_head *bh, *head;

    bh = head = page_buffers(page);
    blocksize = bh->b_size;

    block_start = 0;
    do {
        block_end = block_start + blocksize;
        if (block_end <= from || block_start >= to) {
            if (!buffer_uptodate(bh))
                partial = 1;
        } else {
            set_buffer_uptodate(bh);
            mark_buffer_dirty(bh);
        }
        clear_buffer_new(bh);

        block_start = block_end;
        bh = bh->b_this_page;
    } while (bh != head);
    //...
}

标记了,然后呢?

你可能感兴趣的:(浅尝辄止69-FAT32-内核10)