浅尝辄止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什么时候刷到磁盘上的呢?

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