Date: Sun, 25 Jun 2017 02:03:50 +0000 From: bugzilla-noreply@freebsd.org To: freebsd-fs@FreeBSD.org Subject: [Bug 220185] >> operator does not append in Fuse mounts Message-ID: <bug-220185-3630-Q9RcFgC3yE@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-220185-3630@https.bugs.freebsd.org/bugzilla/> References: <bug-220185-3630@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D220185 Conrad Meyer <cem@freebsd.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|freebsd-fs@FreeBSD.org |cem@freebsd.org Status|New |In Progress --- Comment #1 from Conrad Meyer <cem@freebsd.org> --- I can reproduce this problem with lklfuse (ext4 image). Exact same steps as Ben provided. $ truss sh -c 'echo line4 >> test.txt' ... openat(AT_FDCWD,"test.txt",O_WRONLY|O_APPEND|O_CREAT,0666) =3D 3 (0x3) dup2(0x3,0x1) =3D 1 (0x1) close(3) =3D 0 (0x0) write(1,"line4\n",6) =3D 6 (0x6) >From lklfuse -o debug: unique: 2, opcode: LOOKUP (1), nodeid: 1, insize: 49, pid: 7005 LOOKUP /test.txt getattr /test.txt NODEID: 2 unique: 2, success, outsize: 136 unique: 3, opcode: OPEN (14), nodeid: 2, insize: 48, pid: 7005 open flags: 0x1 /test.txt open[0] flags: 0x1 /test.txt unique: 3, success, outsize: 32 // Flag 0x1 =3D=3D O_WRONLY. I'm not sure if FUSE clients are supposed to handle O_APPEND or if FUSE is supposed to emulate it on their behalf. Either way, it seems to be getting dropped. That said =E2=80=94 it doesn't look like UFS does anything specia= l with the APPEND flag either. After all, multiple file handles can reference the same vnode at different offsets. So the offset should be a property of the file handle, not the vnode. This suggests some higher layer is misbehaving; not individual FUSE filesystems. (Not really surprising, I know.) More from lklfuse -o debug: unique: 4, opcode: GETATTR (3), nodeid: 2, insize: 40, pid: 7005 getattr /test.txt unique: 4, success, outsize: 112 unique: 5, opcode: WRITE (16), nodeid: 2, insize: 70, pid: 7005 write[0] 6 bytes to 0 flags: 0x0 write[0] 6 bytes to 0 unique: 5, success, outsize: 24 // Note: "to 0" (offset 0), "flags: 0x0" (no IO_APPEND) That's a problem. kern_openat() installs O_APPEND from open(2) into the struct file referring= to test.txt. Then in vn_write(), f_flag means that ioflag has IO_APPEND added= .=20 This is passed into VOP_WRITE. What does fs/fuse do with that? Well, there's a check in fuse_write_biobackend() that sets the uio offset to the end of the file if that flag is present. Either we aren't hitting that path, or the uio's offset isn't getting communicated to fuse filesystems. VOP_WRITE -> fuse_vnop_write -> fuse_iop_dispatch(). From there we enter fuse_write_directbackend for IO_DIRECT uio's, or fuse_write_biobackend otherwise. The DIRECT backend completely ignores IO_APPEND. I'd guess we're not hitti= ng that path as the open did not use O_DIRECT. I'm pretty confused by what fuse_write_biobackend() is doing, but it looks = like it may be correct. Maybe we're seeing the DIRECT path. ...haha, yup. fuse_vnop_open(): 1147 /* 1148 * For WRONLY opens, force DIRECT_IO. This is necessa= ry 1149 * since writing a partial block through the buffer ca= che 1150 * will result in a read of the block and that read wo= n't 1151 * be allowed by the WRONLY open. 1152 */ 1153 if (fufh_type =3D=3D FUFH_WRONLY || 1154 (fvdat->flag & FN_DIRECTIO) !=3D 0) 1155 fuse_open_flags =3D FOPEN_DIRECT_IO; Sigh. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-220185-3630-Q9RcFgC3yE>