Date: Mon, 28 Dec 2015 12:14:30 -0500 (EST) From: Rick Macklem <rmacklem@uoguelph.ca> To: freebsd-fs <freebsd-fs@freebsd.org> Subject: fixing a Fuse bug when writing (PR#194293?) Message-ID: <1044566436.145078070.1451322870420.JavaMail.zimbra@uoguelph.ca>
next in thread | raw e-mail | index | archive | help
Hi, I sent a rather long email to a few people, but forgot to cc freebsd-fs@. Here's a shorter version: - When a file on a Fuse mounted fs is opened WRONLY and a partial block is written (when using the buffer cache, not DIRECT_IO), it gets wedged because the buffer cache code attempts to read in the whole block and the read isn't allowed. (I can reproduce this using GlusterFS and I think PR#194293 might be the same problem.) I can think of two ways to fix this: 1 - Make any WRONLY open actually do a RDWR open. The patch at the end of the email does that and fixes the problem for my test case. XXX - I think the problem is that if a process has write but not read access for the file, this RDWR open will fail and that won't make much sense, since it has write access. 2 - Make Fuse always do DIRECT_IO when a file is opened WRONLY. (This seems to happen for GlusterFS, since it seems to always set FOPEN_DIRECT_IO in the Fuse reply to the open for WRONLY, but I suspect other Fuse filesystems don't do this? I reproduced the problem by hacking the code to ignore the FOPEN_DIRECT_IO in the reply for GlusterFS.) I have coded #1 but not #2. However I am now thinking #2 is the better solution, given (XXX) above. Any other ideas or opinions w.r.t. how to fix this? Thanks, rick ps: Here's the patch I came up with for #1: --- fs/fuse/fuse_file.h.xxx 2015-12-27 16:02:53.241174000 -0500 +++ fs/fuse/fuse_file.h 2015-12-27 15:25:01.865156000 -0500 @@ -101,6 +101,9 @@ fuse_filehandle_xlate_from_fflags(int ff if ((fflags & FREAD) && (fflags & FWRITE)) { return FUFH_RDWR; } else if (fflags & (FWRITE)) { + /* See comment in fuse_vnop_open() w.r.t. why FUFH_RDWR is needed. */ + if (datacache != 0) + return FUFH_RDWR; return FUFH_WRONLY; } else if (fflags & (FREAD)) { return FUFH_RDONLY; --- fs/fuse/fuse_vnops.c.sav 2015-12-16 16:24:43.577000000 -0500 +++ fs/fuse/fuse_vnops.c 2015-12-27 16:07:06.683806000 -0500 @@ -276,7 +276,8 @@ fuse_vnop_close(struct vop_close_args *a if (fflag & IO_NDELAY) { return 0; } - fufh_type = fuse_filehandle_xlate_from_fflags(fflag); + fufh_type = fuse_filehandle_xlate_from_fflags(fflag, + fsess_opt_datacache(vnode_mount(vp))); if (!fuse_filehandle_valid(vp, fufh_type)) { int i; @@ -1139,7 +1140,8 @@ fuse_vnop_open(struct vop_open_args *ap) if (isdir) { fufh_type = FUFH_RDONLY; } else { - fufh_type = fuse_filehandle_xlate_from_fflags(mode); + fufh_type = fuse_filehandle_xlate_from_fflags(mode, + fsess_opt_datacache(vnode_mount(vp))); } if (fuse_filehandle_valid(vp, fufh_type)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1044566436.145078070.1451322870420.JavaMail.zimbra>