diff mbox

virtio: fix fsync() on a directory

Message ID 20150529134139.GA32276@rmk-PC.arm.linux.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Russell King May 29, 2015, 1:41 p.m. UTC
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>
---
 virtio/9p.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/virtio/9p.c b/virtio/9p.c
index 2c120fa..5f93e41 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;