Module Name: src Committed By: pho Date: Thu Nov 17 14:20:26 UTC 2016
Modified Files: src/lib/librefuse: refuse.c Log Message: Change the way how puffs_fuse_node_create() behaves. In puffs "create" and "open" are two separate operations with atomicity achieved by locking the parent vnode. In fuse, on the other hand, "create" is actually a create-and-open-atomically and the open flags (O_RDWR, O_APPEND, ...) are passed via fi.flags. So the only way to emulate the fuse semantics is to open the file with dummy flags and then immediately close it. You might think that we could simply use fuse->op.mknod all the time but no, that's not possible because most file systems nowadays expect op.mknod to be called only for non-regular files and many don't even support it. To generate a diff of this commit: cvs rdiff -u -r1.96 -r1.97 src/lib/librefuse/refuse.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/librefuse/refuse.c diff -u src/lib/librefuse/refuse.c:1.96 src/lib/librefuse/refuse.c:1.97 --- src/lib/librefuse/refuse.c:1.96 Sun Dec 30 10:04:22 2012 +++ src/lib/librefuse/refuse.c Thu Nov 17 14:20:25 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: refuse.c,v 1.96 2012/12/30 10:04:22 tron Exp $ */ +/* $NetBSD: refuse.c,v 1.97 2016/11/17 14:20:25 pho Exp $ */ /* * Copyright © 2007 Alistair Crooks. All rights reserved. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: refuse.c,v 1.96 2012/12/30 10:04:22 tron Exp $"); +__RCSID("$NetBSD: refuse.c,v 1.97 2016/11/17 14:20:25 pho Exp $"); #endif /* !lint */ #include <sys/types.h> @@ -765,8 +765,22 @@ puffs_fuse_node_create(struct puffs_user set_fuse_context_uid_gid(pcn->pcn_cred); + memset(&fi, 0, sizeof(fi)); created = 0; if (fuse->op.create) { + /* In puffs "create" and "open" are two separate operations + * with atomicity achieved by locking the parent vnode. In + * fuse, on the other hand, "create" is actually a + * create-and-open-atomically and the open flags (O_RDWR, + * O_APPEND, ...) are passed via fi.flags. So the only way to + * emulate the fuse semantics is to open the file with dummy + * flags and then immediately close it. + * + * You might think that we could simply use fuse->op.mknod all + * the time but no, that's not possible because most file + * systems nowadays expect op.mknod to be called only for + * non-regular files and many don't even support it. */ + fi.flags = O_WRONLY | O_CREAT | O_EXCL; ret = fuse->op.create(path, mode | S_IFREG, &fi); if (ret == 0) created = 1; @@ -782,12 +796,11 @@ puffs_fuse_node_create(struct puffs_user ret = fuse_newnode(pu, path, va, &fi, pni, &pn); /* sweet.. create also open the file */ - if (created) { - struct refusenode *rn; - - rn = pn->pn_data; - rn->flags |= RN_OPEN; - rn->opencount++; + if (created && fuse->op.release) { + struct refusenode *rn = pn->pn_data; + /* The return value of op.release is expected to be + * discarded. */ + (void)fuse->op.release(path, &rn->file_info); } }