Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 May 2016 22:42:57 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r300916 - stable/10/sys/fs/fuse
Message-ID:  <201605282242.u4SMgvph031395@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sat May 28 22:42:56 2016
New Revision: 300916
URL: https://svnweb.freebsd.org/changeset/base/300916

Log:
  MFC: r299753
  Fix fuse to use DIRECT_IO when required.
  
  When a file is opened write-only and a partial block was written,
  buffered I/O would try and read the whole block in. This would
  result in a hung thread, since there was no open (fuse filehandle)
  that allowed reading. This patch avoids the problem by forcing
  DIRECT_IO for this case.
  It also sets DIRECT_IO when the file system specifies the FN_DIRECTIO
  flag in its reply to the open.

Modified:
  stable/10/sys/fs/fuse/fuse_file.c
  stable/10/sys/fs/fuse/fuse_vnops.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/fs/fuse/fuse_file.c
==============================================================================
--- stable/10/sys/fs/fuse/fuse_file.c	Sat May 28 22:27:54 2016	(r300915)
+++ stable/10/sys/fs/fuse/fuse_file.c	Sat May 28 22:42:56 2016	(r300916)
@@ -141,7 +141,17 @@ fuse_filehandle_open(struct vnode *vp,
 	foo = fdi.answ;
 
 	fuse_filehandle_init(vp, fufh_type, fufhp, foo->fh);
-	fuse_vnode_open(vp, foo->open_flags, td);
+
+	/*
+	 * For WRONLY opens, force DIRECT_IO.  This is necessary
+	 * since writing a partial block through the buffer cache
+	 * will result in a read of the block and that read won't
+	 * be allowed by the WRONLY open.
+	 */
+	if (fufh_type == FUFH_WRONLY)
+		fuse_vnode_open(vp, foo->open_flags | FOPEN_DIRECT_IO, td);
+	else
+		fuse_vnode_open(vp, foo->open_flags, td);
 
 out:
 	fdisp_destroy(&fdi);

Modified: stable/10/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- stable/10/sys/fs/fuse/fuse_vnops.c	Sat May 28 22:27:54 2016	(r300915)
+++ stable/10/sys/fs/fuse/fuse_vnops.c	Sat May 28 22:42:56 2016	(r300916)
@@ -1125,6 +1125,7 @@ fuse_vnop_open(struct vop_open_args *ap)
 	struct fuse_vnode_data *fvdat;
 
 	int error, isdir = 0;
+	int32_t fuse_open_flags;
 
 	FS_DEBUG2G("inode=%ju mode=0x%x\n", (uintmax_t)VTOI(vp), mode);
 
@@ -1136,14 +1137,24 @@ fuse_vnop_open(struct vop_open_args *ap)
 	if (vnode_isdir(vp)) {
 		isdir = 1;
 	}
+	fuse_open_flags = 0;
 	if (isdir) {
 		fufh_type = FUFH_RDONLY;
 	} else {
 		fufh_type = fuse_filehandle_xlate_from_fflags(mode);
+		/*
+		 * For WRONLY opens, force DIRECT_IO.  This is necessary
+		 * since writing a partial block through the buffer cache
+		 * will result in a read of the block and that read won't
+		 * be allowed by the WRONLY open.
+		 */
+		if (fufh_type == FUFH_WRONLY ||
+		    (fvdat->flag & FN_DIRECTIO) != 0)
+			fuse_open_flags = FOPEN_DIRECT_IO;
 	}
 
 	if (fuse_filehandle_valid(vp, fufh_type)) {
-		fuse_vnode_open(vp, 0, td);
+		fuse_vnode_open(vp, fuse_open_flags, td);
 		return 0;
 	}
 	error = fuse_filehandle_open(vp, fufh_type, NULL, td, cred);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605282242.u4SMgvph031395>