内存只是暂时的,磁盘才能长长久久。
标记内存为脏
内存里的文件终究要刷到磁盘上的,在write的时候没有刷,什么时候刷呢?
再看一下generic_perform_write
,后面有一个a_ops->write_end
调用。这个a_ops
是struct 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);
//...
}
标记了,然后呢?