Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src - open the file before doing fsync: glusterfs wants that.
details: https://anonhg.NetBSD.org/src/rev/cccd3df57e64
branches: trunk
changeset: 757352:cccd3df57e64
user: manu <manu%NetBSD.org@localhost>
date: Thu Aug 26 13:29:01 2010 +0000
description:
- open the file before doing fsync: glusterfs wants that.
- Automatically call fsync on close for files. If we just close, fsync
will come later and we will have to reopen
- Add a PND_DIRTY flag to keep track of files that really need a sync.
perfuse_node_fsync only calls the FUSE fsync method if there are data
to push.
- Add a PND_OPEN flag to keep track of open files. Checking non NULL
fh is not enough, as some filesystems will always set fh to 0.
- Add a sync diagnostic flag, to watch fsync and dirty flag activity.
Make the fh diagnostic flag more verbose
- Send the fh in setattr (it was hardcoded to 0)
I am now able to build libperfuse in a glusterfs mounted filesystem. Yeah!
diffstat:
lib/libperfuse/ops.c | 230 +++++++++++++++++++++++++++++++++++------
lib/libperfuse/perfuse_if.h | 10 +-
lib/libperfuse/perfuse_priv.h | 4 +-
lib/libperfuse/subr.c | 9 +-
usr.sbin/perfused/debug.c | 3 +-
usr.sbin/perfused/perfused.8 | 4 +-
usr.sbin/perfused/perfused.c | 4 +-
7 files changed, 218 insertions(+), 46 deletions(-)
diffs (truncated from 568 to 300 lines):
diff -r ee3957c7a2c0 -r cccd3df57e64 lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c Thu Aug 26 13:21:50 2010 +0000
+++ b/lib/libperfuse/ops.c Thu Aug 26 13:29:01 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ops.c,v 1.1 2010/08/25 07:16:00 manu Exp $ */
+/* $NetBSD: ops.c,v 1.2 2010/08/26 13:29:01 manu Exp $ */
/*-
* Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -824,7 +824,6 @@
if (error != 0)
return error;
-
return 0;
}
@@ -960,9 +959,14 @@
* so that we can reuse it later
*/
perfuse_new_fh((puffs_cookie_t)pn, foo->fh);
+
#ifdef PERFUSE_DEBUG
if (perfuse_diagflags & PDF_FH)
- DPRINTF("%s: fh = %lld\n", __func__, foo->fh);
+ DPRINTF("%s: opc = %p, file = \"%s\", "
+ "ino = %lld, fh = 0x%llx\n",
+ __func__, (void *)opc,
+ (char *)PNPATH((struct puffs_node *)opc),
+ PERFUSE_NODE_DATA(opc)->pnd_ino, foo->fh);
#endif
out:
ps->ps_destroy_msg(pm);
@@ -982,16 +986,46 @@
perfuse_msg_t *pm;
int op;
uint64_t fh;
+ struct perfuse_node_data *pnd;
struct fuse_release_in *fri;
struct puffs_node *pn;
int error;
ps = puffs_getspecific(pu);
+ pn = (struct puffs_node *)opc;
+ pnd = PERFUSE_NODE_DATA(pn);
- pn = (struct puffs_node *)opc;
+ if (puffs_pn_getvap(pn)->va_type == VDIR)
+ op = FUSE_RELEASEDIR;
+ else
+ op = FUSE_RELEASE;
+
+ if (!(pnd->pnd_flags & PND_OPEN))
+ return EBADF;
+
+ fh = perfuse_get_fh(opc);
- if ((fh = perfuse_get_fh((puffs_cookie_t)pn)) == FUSE_UNKNOWN_FH)
- return EBADF;
+ /*
+ * Sync before close for files
+ * XXX no pcr argument to pass
+ */
+ if ((op == FUSE_RELEASE) && (pnd->pnd_flags & PND_DIRTY)) {
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_SYNC)
+ DPRINTF("%s: SYNC opc = %p, file = \"%s\"\n",
+ __func__, (void*)opc, (char *)PNPATH(pn));
+#endif
+ if ((error = perfuse_node_fsync(pu, opc, NULL, 0, 0, 0)) != 0)
+ return error;
+
+ pnd->pnd_flags &= ~PND_DIRTY;
+
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_SYNC)
+ DPRINTF("%s: CLEAR opc = %p, file = \"%s\"\n",
+ __func__, (void*)opc, (char *)PNPATH((pn)));
+#endif
+ }
/*
* Destroy the filehandle before sending the
@@ -1004,14 +1038,10 @@
#ifdef PERFUSE_DEBUG
if (perfuse_diagflags & PDF_FH)
- DPRINTF("%s: fh = %lld\n", __func__, fh);
+ DPRINTF("%s: opc = %p, ino = %lld, fh = 0x%llx\n",
+ __func__, (void *)opc, pnd->pnd_ino, fh);
#endif
- if (puffs_pn_getvap(pn)->va_type == VDIR)
- op = FUSE_RELEASEDIR;
- else
- op = FUSE_RELEASE;
-
/*
* release_flags may be set to FUSE_RELEASE_FLUSH
* to flush locks. lock_owner must be set in that case
@@ -1024,12 +1054,18 @@
fri->lock_owner = PERFUSE_NODE_DATA(pn)->pnd_lock_owner;
fri->flags = (fri->lock_owner != 0) ? FUSE_RELEASE_FLUSH : 0;
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_FH)
+ DPRINTF("%s: opc = %p, ino = %lld, fh = 0x%llx\n",
+ __func__, (void *)opc, pnd->pnd_ino, fri->fh);
+#endif
+
if ((error = XCHG_MSG(ps, pu, pm, NO_PAYLOAD_REPLY_LEN)) != 0)
goto out;
out:
if (error != 0)
- DWARNX("%s: freed fh = %lld but filesystem returned error = %d",
+ DWARNX("%s: freed fh = 0x%llx but filesystem returned error = %d",
__func__, fh, error);
ps->ps_destroy_msg(pm);
@@ -1077,8 +1113,14 @@
fgi = GET_INPAYLOAD(ps, pm, fuse_getattr_in);
fgi->getattr_flags = 0;
fgi->dummy = 0;
- fgi->fh = 0;
+ fgi->fh = perfuse_get_fh(opc);
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_FH)
+ DPRINTF("%s: opc = %p, ino = %lld, fh = 0x%llx\n",
+ __func__, (void *)opc,
+ PERFUSE_NODE_DATA(opc)->pnd_ino, fgi->fh);
+#endif
if ((error = XCHG_MSG(ps, pu, pm, sizeof(*fao))) != 0) {
ps->ps_destroy_msg(pm);
goto out;
@@ -1161,7 +1203,8 @@
fsi = GET_INPAYLOAD(ps, pm, fuse_setattr_in);
fsi->valid = 0;
- if ((fh = perfuse_get_fh(opc)) != FUSE_UNKNOWN_FH) {
+ if (PERFUSE_NODE_DATA(opc)->pnd_flags & PND_OPEN) {
+ fh = perfuse_get_fh(opc);
fsi->fh = fh;
fsi->valid |= FUSE_FATTR_FH;
}
@@ -1235,6 +1278,12 @@
fpi->kh = 0;
fpi->flags = 0;
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_FH)
+ DPRINTF("%s: opc = %p, ino = %lld, fh = 0x%llx\n",
+ __func__, (void *)opc,
+ PERFUSE_NODE_DATA(opc)->pnd_ino, fpi->fh);
+#endif
if ((error = XCHG_MSG(ps, pu, pm, sizeof(*fpo))) != 0)
goto out;
@@ -1272,9 +1321,15 @@
{
perfuse_msg_t *pm;
struct perfuse_state *ps;
+ struct perfuse_node_data *pnd;
struct fuse_fsync_in *ffi;
+ uint64_t fh;
+ int open_self;
int error;
+ pm = NULL;
+ open_self = 0;
+
/*
* If we previously detected it as unimplemented,
* skip the call to the filesystem.
@@ -1284,24 +1339,73 @@
return ENOSYS;
/*
+ * Do not sync if there are no change to sync
+ * XXX remove that testif we implement mmap
+ */
+ pnd = PERFUSE_NODE_DATA(opc);
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_SYNC)
+ DPRINTF("%s: TEST opc = %p, file = \"%s\" is %sdirty\n",
+ __func__, (void*)opc,
+ (char *)PNPATH((struct puffs_node *)opc),
+ pnd->pnd_flags & PND_DIRTY ? "" : "not ");
+#endif
+ if (!(pnd->pnd_flags & PND_DIRTY))
+ return 0;
+
+ /*
+ * It seems NetBSD can call fsync without open first
+ * glusterfs complain in such a situation:
+ * "FSYNC() ERR => -1 (Invalid argument)"
+ */
+ if (!(pnd->pnd_flags & PND_OPEN)) {
+ if ((error = perfuse_node_open(pu, opc, FREAD, pcr)) != 0)
+ goto out;
+ open_self = 1;
+ }
+
+ fh = perfuse_get_fh(opc);
+
+ /*
* If fsync_flags is set, meta data should not be flushed.
*/
pm = ps->ps_new_msg(pu, opc, FUSE_FSYNC, sizeof(*ffi), NULL);
ffi = GET_INPAYLOAD(ps, pm, fuse_fsync_in);
- ffi->fh = perfuse_get_fh(opc);
+ ffi->fh = fh;
ffi->fsync_flags = (flags & FFILESYNC) ? 0 : 1;
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_FH)
+ DPRINTF("%s: opc = %p, ino = %lld, fh = 0x%llx\n",
+ __func__, (void *)opc,
+ PERFUSE_NODE_DATA(opc)->pnd_ino, ffi->fh);
+#endif
+
if ((error = XCHG_MSG(ps, pu, pm, NO_PAYLOAD_REPLY_LEN)) != 0)
goto out;
/*
- * No reply beyond fuse_out_header: nothing to do on success.
+ * No reply beyond fuse_out_header: nothing to do on success
+ * just clear the dirty flag
*/
+ pnd->pnd_flags &= ~PND_DIRTY;
+
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_SYNC)
+ DPRINTF("%s: CLEAR opc = %p, file = \"%s\"\n",
+ __func__, (void*)opc,
+ (char *)PNPATH((struct puffs_node *)opc));
+#endif
+
out:
if (error == ENOSYS)
ps->ps_flags |= PS_NO_FSYNC;
- ps->ps_destroy_msg(pm);
+ if (pm != NULL)
+ ps->ps_destroy_msg(pm);
+
+ if (open_self)
+ (void)perfuse_node_close(pu, opc, 0, pcr);
return error;
}
@@ -1522,6 +1626,7 @@
DERR(EX_OSERR, "puffs_inval_namecache_node failed");
puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2);
+
out:
ps->ps_destroy_msg(pm);
@@ -1619,15 +1724,21 @@
* It seems NetBSD can call readdir without open first
* libfuse will crash if it is done that way, hence open first.
*/
- if ((fh = perfuse_get_fh(opc)) == FUSE_UNKNOWN_FH) {
+ if (!(PERFUSE_NODE_DATA(opc)->pnd_flags & PND_OPEN)) {
if ((error = perfuse_node_open(pu, opc, FREAD, pcr)) != 0)
goto out;
open_self = 1;
-
- if ((fh = perfuse_get_fh(opc)) == FUSE_UNKNOWN_FH)
- DERRX(EX_SOFTWARE, "open directory without fh");
}
+ fh = perfuse_get_fh(opc);
+
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_FH)
+ DPRINTF("%s: opc = %p, ino = %lld, fh = 0x%llx\n",
+ __func__, (void *)opc,
+ PERFUSE_NODE_DATA(opc)->pnd_ino, fh);
+#endif
+
pnd->pnd_all_fd = NULL;
pnd->pnd_all_fd_len = 0;
fd_offset = 0;
@@ -1783,31 +1894,32 @@
{
struct perfuse_state *ps;
perfuse_msg_t *pm;
+ struct perfuse_node_data *pnd;
struct fuse_forget_in *ffi;
struct puffs_node *pn;
struct puffs_node *pn_root;
ps = puffs_getspecific(pu);
+ pnd = PERFUSE_NODE_DATA(opc);
/*
* Make sure open files are properly closed when reclaimed.
Home |
Main Index |
Thread Index |
Old Index