Skip to contentSkip to conversation

virtio: fix fsync() on a directory

PATCH New Russell King 1 participant 1 message May 29, 2015 KVM

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---
 virtio/9p.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
virtio/9p.c +8 -3
index 2c120fa..5f93e41 100644
@@ -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;
Signature · 1 line
2.1.0