summaryrefslogtreecommitdiffstats
path: root/xlators/features/bit-rot/src/stub/bit-rot-stub.h
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/bit-rot/src/stub/bit-rot-stub.h')
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub.h269
1 files changed, 269 insertions, 0 deletions
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.h b/xlators/features/bit-rot/src/stub/bit-rot-stub.h
new file mode 100644
index 00000000000..d565112b1ad
--- /dev/null
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.h
@@ -0,0 +1,269 @@
+ /*
+ Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+#ifndef __BIT_ROT_STUB_H__
+#define __BIT_ROT_STUB_H__
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs.h"
+#include "logging.h"
+#include "dict.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "call-stub.h"
+
+#include "bit-rot-common.h"
+
+typedef int (br_stub_version_cbk) (call_frame_t *, void *,
+ xlator_t *, int32_t, int32_t, dict_t *);
+
+typedef struct br_stub_inode_ctx {
+ int need_writeback; /* does the inode need
+ a writeback to disk? */
+ unsigned long currentversion; /* ongoing version */
+
+ struct release {
+ int32_t ordflags;
+ unsigned long opencount; /* number of open()s before
+ final release() */
+ unsigned long releasecount; /* number of release()s */
+ } releasectx;
+#define BR_STUB_REQUIRE_RELEASE_CBK 0x0E0EA0E
+} br_stub_inode_ctx_t;
+
+
+#define I_DIRTY (1<<0) /* inode needs writeback */
+#define WRITEBACK_DURABLE 1 /* writeback is durable */
+
+/**
+ * This could just have been a plain struct without unions and all,
+ * but we may need additional things in the future.
+ */
+typedef struct br_stub_local {
+ call_stub_t *fopstub; /* stub for original fop */
+
+ int versioningtype; /* not much used atm */
+
+ union {
+ struct br_stub_ctx {
+ fd_t *fd;
+ uuid_t gfid;
+ inode_t *inode;
+ unsigned long version;
+ gf_boolean_t markdirty;
+ } context;
+ } u;
+} br_stub_local_t;
+
+#define BR_STUB_FULL_VERSIONING (1<<0)
+#define BR_STUB_INCREMENTAL_VERSIONING (1<<1)
+
+typedef struct br_stub_private {
+ gf_boolean_t go;
+
+ uint32_t boot[2];
+ char export[PATH_MAX];
+
+ struct mem_pool *local_pool;
+} br_stub_private_t;
+
+/* inode writeback helpers */
+static inline void
+__br_stub_mark_inode_dirty (br_stub_inode_ctx_t *ctx)
+{
+ ctx->need_writeback |= I_DIRTY;
+}
+
+static inline void
+__br_stub_mark_inode_synced (br_stub_inode_ctx_t *ctx)
+{
+ ctx->need_writeback &= ~I_DIRTY;
+}
+
+static inline int
+__br_stub_is_inode_dirty (br_stub_inode_ctx_t *ctx)
+{
+ return (ctx->need_writeback & I_DIRTY);
+}
+
+static inline int
+br_stub_require_release_call (xlator_t *this, fd_t *fd)
+{
+ int32_t ret = 0;
+
+ ret = fd_ctx_set (fd, this,
+ (uint64_t)(long)BR_STUB_REQUIRE_RELEASE_CBK);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "could not set fd context (for release callback");
+ return ret;
+}
+
+/* get/set inode context helpers */
+
+static inline int
+__br_stub_get_inode_ctx (xlator_t *this,
+ inode_t *inode, uint64_t *ctx)
+{
+ return __inode_ctx_get (inode, this, ctx);
+}
+
+static inline int
+br_stub_get_inode_ctx (xlator_t *this,
+ inode_t *inode, uint64_t *ctx)
+{
+ return inode_ctx_get (inode, this, ctx);
+}
+
+static inline int
+br_stub_set_inode_ctx (xlator_t *this,
+ inode_t *inode, br_stub_inode_ctx_t *ctx)
+{
+ uint64_t ctx_addr = (uint64_t) ctx;
+ return inode_ctx_set (inode, this, &ctx_addr);
+}
+
+/* version get/set helpers */
+
+static inline unsigned long
+__br_stub_writeback_version (br_stub_inode_ctx_t *ctx)
+{
+ return (ctx->currentversion + 1);
+}
+
+static inline void
+__br_stub_set_ongoing_version (br_stub_inode_ctx_t *ctx, unsigned long version)
+{
+ ctx->currentversion = version;
+}
+
+static inline void
+__br_stub_reset_release_counters (br_stub_inode_ctx_t *ctx)
+{
+ ctx->releasectx.ordflags = 0;
+ ctx->releasectx.opencount = 0;
+ ctx->releasectx.releasecount = 0;
+}
+
+static inline void
+__br_stub_track_release (br_stub_inode_ctx_t *ctx)
+{
+ ++ctx->releasectx.releasecount;
+}
+
+static inline void
+___br_stub_track_open (br_stub_inode_ctx_t *ctx)
+{
+ ++ctx->releasectx.opencount;
+}
+
+static inline void
+___br_stub_track_open_flags (fd_t *fd, br_stub_inode_ctx_t *ctx)
+{
+ ctx->releasectx.ordflags |= fd->flags;
+}
+
+static inline void
+__br_stub_track_openfd (fd_t *fd, br_stub_inode_ctx_t *ctx)
+{
+ ___br_stub_track_open (ctx);
+ ___br_stub_track_open_flags (fd, ctx);
+}
+
+static inline int
+__br_stub_can_trigger_release (inode_t *inode,
+ br_stub_inode_ctx_t *ctx,
+ unsigned long *version, int32_t *flags)
+{
+ if (list_empty (&inode->fd_list)
+ && (ctx->releasectx.releasecount == ctx->releasectx.opencount)) {
+ if (flags)
+ *flags = htonl (ctx->releasectx.ordflags);
+ if (version)
+ *version = htonl (ctx->currentversion);
+
+ __br_stub_reset_release_counters (ctx);
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline int32_t
+br_stub_get_ongoing_version (xlator_t *this,
+ inode_t *inode, unsigned long *version)
+{
+ int32_t ret = 0;
+ uint64_t ctx_addr = 0;
+ br_stub_inode_ctx_t *ctx = NULL;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx_addr);
+ if (ret < 0)
+ goto unblock;
+ ctx = (br_stub_inode_ctx_t *) (long) ctx_addr;
+ *version = ctx->currentversion;
+ }
+ unblock:
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
+/**
+ * fetch the current version from inode and return the context.
+ * inode->lock should be held before invoking this as context
+ * *needs* to be valid in the caller.
+ */
+static inline br_stub_inode_ctx_t *
+__br_stub_get_ongoing_version_ctx (xlator_t *this,
+ inode_t *inode, unsigned long *version)
+{
+ int32_t ret = 0;
+ uint64_t ctx_addr = 0;
+ br_stub_inode_ctx_t *ctx = NULL;
+
+ ret = __inode_ctx_get (inode, this, &ctx_addr);
+ if (ret < 0)
+ return NULL;
+ ctx = (br_stub_inode_ctx_t *) (long) ctx_addr;
+ if (version)
+ *version = ctx->currentversion;
+
+ return ctx;
+}
+
+/* filter for xattr fetch */
+static inline int
+br_stub_is_internal_xattr (const char *name)
+{
+ if (name
+ && ((strncmp (name, BITROT_CURRENT_VERSION_KEY,
+ strlen (BITROT_CURRENT_VERSION_KEY)) == 0)
+ || (strncmp (name, BITROT_SIGNING_VERSION_KEY,
+ strlen (BITROT_SIGNING_VERSION_KEY)) == 0)))
+ return 1;
+ return 0;
+}
+
+static inline void
+br_stub_remove_vxattrs (dict_t *xattr)
+{
+ if (xattr) {
+ dict_del (xattr, BITROT_CURRENT_VERSION_KEY);
+ dict_del (xattr, BITROT_SIGNING_VERSION_KEY);
+ }
+}
+
+#endif /* __BIT_ROT_STUB_H__ */