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. Tested by: nishida@asusa.net, freebsd@moosefs.com PR: 194293, 206238 MFC after: 2 weeks
This commit is contained in:
parent
ccfee76778
commit
8d3f87b2b7
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user