[12/30] virtiofsd: Make fsync work even if only inode is passed in
diff mbox series

Message ID 20191021105832.36574-13-dgilbert@redhat.com
State New
Headers show
Series
  • virtiofs daemon (base)
Related show

Commit Message

Dr. David Alan Gilbert Oct. 21, 2019, 10:58 a.m. UTC
From: Vivek Goyal <vgoyal@redhat.com>

If caller has not sent file handle in request, then using inode, retrieve
the fd opened using O_PATH and use that to open file again and issue
fsync. This will be needed when dax_flush() calls fsync. At that time
we only have inode information (and not file).

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 contrib/virtiofsd/fuse_lowlevel.c  |  9 ++++++---
 contrib/virtiofsd/passthrough_ll.c | 24 ++++++++++++++++++++++--
 2 files changed, 28 insertions(+), 5 deletions(-)

Patch
diff mbox series

diff --git a/contrib/virtiofsd/fuse_lowlevel.c b/contrib/virtiofsd/fuse_lowlevel.c
index ff68ec0c9d..6fe7506ead 100644
--- a/contrib/virtiofsd/fuse_lowlevel.c
+++ b/contrib/virtiofsd/fuse_lowlevel.c
@@ -1083,9 +1083,12 @@  static void do_fsync(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
 	memset(&fi, 0, sizeof(fi));
 	fi.fh = arg->fh;
 
-	if (req->se->op.fsync)
-		req->se->op.fsync(req, nodeid, datasync, &fi);
-	else
+	if (req->se->op.fsync) {
+		if (fi.fh == (uint64_t)-1)
+			req->se->op.fsync(req, nodeid, datasync, NULL);
+		else
+			req->se->op.fsync(req, nodeid, datasync, &fi);
+	} else
 		fuse_reply_err(req, ENOSYS);
 }
 
diff --git a/contrib/virtiofsd/passthrough_ll.c b/contrib/virtiofsd/passthrough_ll.c
index 72fae9d10b..63a32c87c3 100644
--- a/contrib/virtiofsd/passthrough_ll.c
+++ b/contrib/virtiofsd/passthrough_ll.c
@@ -863,10 +863,30 @@  static void lo_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
 {
 	int res;
 	(void) ino;
+	int fd;
+	char *buf;
+
+	fuse_log(FUSE_LOG_DEBUG, "lo_fsync(ino=%" PRIu64 ", fi=0x%p)\n", ino,
+		 (void *)fi);
+
+	if (!fi) {
+		res = asprintf(&buf, "/proc/self/fd/%i", lo_fd(req, ino));
+		if (res == -1)
+			return (void) fuse_reply_err(req, errno);
+
+		fd = open(buf, O_RDWR);
+		free(buf);
+		if (fd == -1)
+			return (void) fuse_reply_err(req, errno);
+	} else
+		fd = fi->fh;
+
 	if (datasync)
-		res = fdatasync(fi->fh);
+		res = fdatasync(fd);
 	else
-		res = fsync(fi->fh);
+		res = fsync(fd);
+	if (!fi)
+		close(fd);
 	fuse_reply_err(req, res == -1 ? errno : 0);
 }