浅尝辄止68-FAT32-内核9

文件打开了,我们就来写一写。

write

系统调用write定义在kernel/fs/read_write.c,通过vfs_write调用file->f_op->write来写入文件。

SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
        size_t, count)
{
    struct fd f = fdget_pos(fd);
    ssize_t ret = -EBADF;

    if (f.file) {
        loff_t pos = file_pos_read(f.file);
        ret = vfs_write(f.file, buf, count, &pos);
        if (ret >= 0)
            file_pos_write(f.file, pos);
        fdput_pos(f);
    }

    return ret;
}

FAT的文件操作如下,定义在kernel/fs/fat/file.c,可以看到.write=new_sync_write,即file->f_op->write=new_sync_write
new_sync_write又调用了filp->f_op->write_iter,即generic_file_write_iter

const struct file_operations fat_file_operations = {
    .llseek     = generic_file_llseek,
    .read       = new_sync_read,
    .write      = new_sync_write,
    .read_iter  = generic_file_read_iter,
    .write_iter = generic_file_write_iter,
    .mmap       = generic_file_mmap,
    .release    = fat_file_release,
    .unlocked_ioctl = fat_generic_ioctl,
#ifdef CONFIG_COMPAT
    .compat_ioctl   = fat_generic_compat_ioctl,
#endif
    .fsync      = fat_file_fsync,
    .splice_read    = generic_file_splice_read,
};

generic_file_write_iter定义在kernel/mm/filemap.c,进一步是__generic_file_write_iter==>generic_perform_write

ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
    struct file *file = iocb->ki_filp;
    struct inode *inode = file->f_mapping->host;
    ssize_t ret;

    mutex_lock(&inode->i_mutex);
    ret = __generic_file_write_iter(iocb, from);
    mutex_unlock(&inode->i_mutex);

    if (ret > 0) {
        ssize_t err;

        err = generic_write_sync(file, iocb->ki_pos - ret, ret);
        if (err < 0)
            ret = err;
    }
    return ret;
}

简化如下,iov_iter_copy_from_user_atomic就是一个类似于memcpy的函数,它把用户buffer的内容复制到内存页中。

ssize_t generic_perform_write(struct file *file,
                struct iov_iter *i, loff_t pos)
{
    //...
    copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
    //...
}

其实到这里,一般的write流程就结束了,所谓内存页也只是某块内存,也就是write结束时,内容并没有写到磁盘中。如果这时候突然断电,磁盘里是没有更新的。

内存里的脏buffer什么时候刷到磁盘上的呢?

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 7,915评论 0 3
  • 进程 创建 创建进程用fork()函数。fork()为子进程创建新的地址空间并且拷贝页表。子进程的虚拟地址空间...
    梅花怒阅读 6,028评论 0 7
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 9,406评论 0 5
  • 春风一度花轻暮 晚来雁栖渡 闲卧碧波慢云庐 醉依玉臂曳微步 漪漪偎渚 昵昵归鹭 何处飞丝弥寂路 莫问逍遥还几度 且...
    茗香酒影阅读 1,621评论 0 1
  • 1.早起做早餐,送儿子上学。 2.到仙女山办理避暑房相关事宜。 3.途中听一个课件。
    胡月星阅读 1,112评论 0 0

友情链接更多精彩内容