svn commit: r300916 - stable/10/sys/fs/fuse
Rick Macklem
rmacklem at FreeBSD.org
Sat May 28 22:42:58 UTC 2016
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);
More information about the svn-src-stable-10
mailing list