Linux内核vfs_write函数混乱

时间:2019-08-01 16:05:55

标签: c linux linux-kernel filesystems vfs

我正在查看旧的Linux内核代码(3.10.1),尤其是IO路径。

因此,当IO进入VFS层时,将调用函数vfs_write()

在这里我可以看到对file->f_op->write()的调用,这是一个阻塞调用,正如系统调用write()的手册页所说。

代码中的另一个选项是未定义file->f_op->write指针时,在这种情况下vfs_write()会调用do_sync_write()

do_sync_write()继续调用filp->f_op->aio_write(),这是一个异步调用,正如aio_write()的手册页所述。

现在,我的问题是,当函数do_sync_write()显然可以继续调用异步IO函数时,为什么将其命名为“ sync”?

我可能会丢失一些东西,或者那段时间曾经在这里犯过大错?

函数定义供参考,

ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
{
    ssize_t ret;

    if (!(file->f_mode & FMODE_WRITE))
        return -EBADF;
    if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
        return -EINVAL;
    if (unlikely(!access_ok(VERIFY_READ, buf, count)))
        return -EFAULT;

    ret = rw_verify_area(WRITE, file, pos, count);
        if (ret >= 0) {
        count = ret;
        file_start_write(file);
        if (file->f_op->write)
            ret = file->f_op->write(file, buf, count, pos);
        else
            ret = do_sync_write(file, buf, count, pos);
        if (ret > 0) {
            fsnotify_modify(file);
            add_wchar(current, ret);
        }
        inc_syscw(current);
        file_end_write(file);
    }

    return ret;
}



ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
    struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
    struct kiocb kiocb;
    ssize_t ret;

    init_sync_kiocb(&kiocb, filp);
    kiocb.ki_pos = *ppos;
    kiocb.ki_left = len;
    kiocb.ki_nbytes = len;

    ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
    if (-EIOCBQUEUED == ret)
        ret = wait_on_sync_kiocb(&kiocb);
    *ppos = kiocb.ki_pos;
    return ret;
}

1 个答案:

答案 0 :(得分:0)

  

当函数do_sync_write()显然可以继续调用异步IO函数时,为什么将其命名为“ sync”?

它调用异步功能,然后使用

等待其完成

ret = wait_on_sync_kiocb(&kiocb);

因此,从do_sync_write函数的调用者的角度来看,整个函数的行为都是同步的。