diff options
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.h | 269 |
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__ */ |