Module Name: src Committed By: manu Date: Thu Sep 9 09:12:35 UTC 2010
Modified Files: src/lib/libperfuse: ops.c perfuse_priv.h Log Message: - call FSYNCDIR for directories - directories can be open R/W (for FSYNCDIR) - do not skip calls to FSYNC or FSYNCDIR if the filesystem returned ENOSYS: it may change its mind, and it may also actually do something when retunring ENOSYS - When FSYNC and FSYNCDIR return ENOSYS, do not report it to kernel (silent failure) To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/lib/libperfuse/ops.c cvs rdiff -u -r1.8 -r1.9 src/lib/libperfuse/perfuse_priv.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libperfuse/ops.c diff -u src/lib/libperfuse/ops.c:1.13 src/lib/libperfuse/ops.c:1.14 --- src/lib/libperfuse/ops.c:1.13 Tue Sep 7 16:58:13 2010 +++ src/lib/libperfuse/ops.c Thu Sep 9 09:12:35 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ops.c,v 1.13 2010/09/07 16:58:13 manu Exp $ */ +/* $NetBSD: ops.c,v 1.14 2010/09/09 09:12:35 manu Exp $ */ /*- * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. @@ -62,7 +62,7 @@ static void requeue_request(struct puffs_usermount *, puffs_cookie_t opc, enum perfuse_qtype); static int dequeue_requests(struct perfuse_state *, - puffs_cookie_t opc, enum perfuse_qtype, int); + puffs_cookie_t opc, enum perfuse_qtype, int); #define DEQUEUE_ALL 0 /* @@ -359,6 +359,10 @@ */ error = XCHG_MSG(ps, pu, pm, sizeof(struct fuse_attr_out)); + /* + * The parent directory needs a sync + */ + PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; out: ps->ps_destroy_msg(pm); @@ -1010,6 +1014,10 @@ fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr); puffs_newinfo_setcookie(pni, pn); + /* + * The parent directory needs a sync + */ + PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; out: ps->ps_destroy_msg(pm); @@ -1132,11 +1140,7 @@ /* * Do not open twice, and do not reopen for reading * if we already have write handle. - * Directories are always open with read access only, - * whatever flags we get. */ - if (op == FUSE_OPENDIR) - mode = (mode & ~(FREAD|FWRITE)) | FREAD; if ((mode & FREAD) && (pnd->pnd_flags & PND_RFH)) return 0; if ((mode & FWRITE) && (pnd->pnd_flags & PND_WFH)) @@ -1543,6 +1547,7 @@ off_t offlo; off_t offhi; { + int op; perfuse_msg_t *pm; struct perfuse_state *ps; struct perfuse_node_data *pnd; @@ -1553,18 +1558,16 @@ pm = NULL; open_self = 0; - - /* - * If we previously detected it as unimplemented, - * skip the call to the filesystem. - */ ps = puffs_getspecific(pu); - if (ps->ps_flags == PS_NO_FSYNC) - return ENOSYS; + + if (puffs_pn_getvap((struct puffs_node *)opc)->va_type == VDIR) + op = FUSE_FSYNCDIR; + else /* VREG but also other types such as VLNK */ + op = FUSE_FSYNC; /* * Do not sync if there are no change to sync - * XXX remove that test if we implement mmap + * XXX remove that test on files if we implement mmap */ pnd = PERFUSE_NODE_DATA(opc); #ifdef PERFUSE_DEBUG @@ -1582,7 +1585,7 @@ * glusterfs complain in such a situation: * "FSYNC() ERR => -1 (Invalid argument)" */ - if (!(pnd->pnd_flags & PND_OPEN)) { + if (!(pnd->pnd_flags & PND_WFH)) { if ((error = perfuse_node_open(pu, opc, FWRITE, pcr)) != 0) goto out; open_self = 1; @@ -1593,7 +1596,7 @@ /* * If fsync_flags is set, meta data should not be flushed. */ - pm = ps->ps_new_msg(pu, opc, FUSE_FSYNC, sizeof(*ffi), NULL); + pm = ps->ps_new_msg(pu, opc, op, sizeof(*ffi), NULL); ffi = GET_INPAYLOAD(ps, pm, fuse_fsync_in); ffi->fh = fh; ffi->fsync_flags = (flags & FFILESYNC) ? 0 : 1; @@ -1622,8 +1625,11 @@ #endif out: + /* + * ENOSYS is not returned to kernel, + */ if (error == ENOSYS) - ps->ps_flags |= PS_NO_FSYNC; + error = 0; if (pm != NULL) ps->ps_destroy_msg(pm); @@ -1683,6 +1689,7 @@ DERRX(EX_SOFTWARE, "%s: targ is NULL", __func__); ps = puffs_getspecific(pu); + pnd = PERFUSE_NODE_DATA(opc); pn = (struct puffs_node *)targ; name = basename_r((char *)PNPATH(pn)); len = strlen(name) + 1; @@ -1704,6 +1711,11 @@ /* * Reclaim should take care of decreasing pnd_childcount */ + + /* + * The parent directory needs a sync + */ + PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; out: ps->ps_destroy_msg(pm); @@ -1890,6 +1902,10 @@ PERFUSE_NODE_DATA(targ)->pnd_flags |= PND_REMOVED; + /* + * The parent directory needs a sync + */ + PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; out: ps->ps_destroy_msg(pm); Index: src/lib/libperfuse/perfuse_priv.h diff -u src/lib/libperfuse/perfuse_priv.h:1.8 src/lib/libperfuse/perfuse_priv.h:1.9 --- src/lib/libperfuse/perfuse_priv.h:1.8 Mon Sep 6 01:40:24 2010 +++ src/lib/libperfuse/perfuse_priv.h Thu Sep 9 09:12:35 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse_priv.h,v 1.8 2010/09/06 01:40:24 manu Exp $ */ +/* $NetBSD: perfuse_priv.h,v 1.9 2010/09/09 09:12:35 manu Exp $ */ /*- * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. @@ -44,7 +44,6 @@ uid_t ps_owner_uid; int ps_flags; #define PS_NO_ACCESS 0x0001 /* access is unimplemented; */ -#define PS_NO_FSYNC 0x0002 /* fsync is unimplemented */ #define PS_NO_CREAT 0x0004 /* create is unimplemented */ #define PS_INLOOP 0x0008 /* puffs mainloop started */ long ps_fsid;