diff options
author | Russell King <rmk@arm.linux.org.uk> | 2015-05-29 14:41:39 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2015-06-01 17:54:09 +0100 |
commit | 644140ef4b54c2b047612a2f52bbde84766dabd6 (patch) | |
tree | 17f48471ca7939e1f3c9fb481d4c65559b8ab581 | |
parent | edb4a8a0e47a459ee313607b5ed3109de0572d77 (diff) | |
download | kvmtool-644140ef4b54c2b047612a2f52bbde84766dabd6.tar.gz |
virtio: fix fsync() on a directory
dpkg in the guest fails when it tries to use fsync() on a directory:
openat(AT_FDCWD, "/var/lib/dpkg", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 4
fsync(4) = -1 EINVAL (Invalid argument)
stracing lkvm shows that this is converted to:
openat(AT_FDCWD, "/root/rootfs-32//var/lib/dpkg", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 368
fsync(0) = -1 EINVAL (Invalid argument)
In other words, we sync against the wrong file descriptor. This case
is not handled in the kvmtool code, let's add support for it.
Signed-off-by: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | virtio/9p.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/virtio/9p.c b/virtio/9p.c index a68a5eb4..66dcc26b 100644 --- a/virtio/9p.c +++ b/virtio/9p.c @@ -886,17 +886,22 @@ err_out: static void virtio_p9_fsync(struct p9_dev *p9dev, struct p9_pdu *pdu, u32 *outlen) { - int ret; + int ret, fd; struct p9_fid *fid; u32 fid_val, datasync; virtio_p9_pdu_readf(pdu, "dd", &fid_val, &datasync); fid = get_fid(p9dev, fid_val); + if (fid->dir) + fd = dirfd(fid->dir); + else + fd = fid->fd; + if (datasync) - ret = fdatasync(fid->fd); + ret = fdatasync(fd); else - ret = fsync(fid->fd); + ret = fsync(fd); if (ret < 0) goto err_out; *outlen = pdu->write_offset; |