🐷

writeシステムコール

2023/01/06に公開

writeシステムコール

writeシステムコールを実行すると、以下の順に実行されます。

ext4の場合
write()
  ksys_write()
    vfs_write()
      ext4_file_write_iter()

fs/read_write.c


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_mode & FMODE_CAN_WRITE))
                return -EINVAL;
        if (unlikely(!access_ok(buf, count)))
                return -EFAULT;

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


ssize_t ksys_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, *ppos = file_ppos(f.file);
                if (ppos) {
                        pos = *ppos;
                        ppos = &pos;
                }
                ret = vfs_write(f.file, buf, count, ppos);
                if (ret >= 0 && ppos)
                        f.file->f_pos = pos;
                fdput_pos(f);
        }

        return ret;
}


SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
                size_t, count)
{
        return ksys_write(fd, buf, count);
}



vfs_write()から先はファイルシステムに依存します。

if (file->f_op->write)
  ret = file->f_op->write(file, buf, count, pos);
else if (file->f_op->write_iter)
  ret = new_sync_write(file, buf, count, pos);

ファイルシステムを確認します。

$ df -T
Filesystem     Type  1K-blocks     Used Available Use% Mounted on
/dev/sda2      ext4  245006620 57383404 175104768  25% /

ext4が使われています。

fs/ext4/file.c
const struct file_operations ext4_file_operations = {
        .llseek         = ext4_llseek,
        .read_iter      = ext4_file_read_iter,
        .write_iter     = ext4_file_write_iter,
        
};

関数ポインタでext4_file_write_iterが実行されることになります。

Discussion