diff options
author | Joseph Fernandes <josferna@redhat.com> | 2015-04-24 19:22:44 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-05-06 04:40:55 -0700 |
commit | cb11dd91a6cc296e4a3808364077f4eacb810e48 (patch) | |
tree | 8c048c7e4f2ff13a2a47e893ff5a666082fef94f /xlators/features/changetimerecorder/src/ctr-helper.h | |
parent | 306585d2e57aadc7d15951ab1114d49fd9dbf5aa (diff) | |
download | glusterfs-cb11dd91a6cc296e4a3808364077f4eacb810e48.tar.gz glusterfs-cb11dd91a6cc296e4a3808364077f4eacb810e48.tar.xz glusterfs-cb11dd91a6cc296e4a3808364077f4eacb810e48.zip |
ctr/xlator: Named lookup heal of pre-existing files, before ctr was ON.
Problem: The CTR xlator records file meta (heat/hardlinks)
into the data. This works fine for files which are created
after ctr xlator is switched ON. But for files which were
created before CTR xlator is ON, CTR xlator is not able to
record either of the meta i.e heat or hardlinks. Thus making
those files immune to promotions/demotions.
Solution: The solution that is implemented in this patch is
do ctr-db heal of all those pre-existent files, using named lookup.
For this purpose we use the inode-xlator context variable option
in gluster.
The inode-xlator context variable for ctr xlator will have the
following,
a. A Lock for the context variable
b. A hardlink list: This list represents the successful looked
up hardlinks.
These are the scenarios when the hardlink list is updated:
1) Named-Lookup: Whenever a named lookup happens on a file, in the
wind path we copy all required hardlink and inode information to
ctr_db_record structure, which resides in the frame->local variable.
We dont update the database in wind. During the unwind, we read the
information from the ctr_db_record and ,
Check if the inode context variable is created, if not we create it.
Check if the hard link is there in the hardlink list.
If its not there we add it to the list and send a update to the
database using libgfdb.
Please note: The database transaction can fail(and we ignore) as there
already might be a record in the db. This update to the db is to heal
if its not there.
If its there in the list we ignore it.
2) Inode Forget: Whenever an inode forget hits we clear the hardlink list in
the inode context variable and delete the inode context variable.
Please note: An inode forget may happen for two reason,
a. when the inode is delete.
b. the in-memory inode is evicted from the inode table due to cache limits.
3) create: whenever a create happens we create the inode context variable and
add the hardlink. The database updation is done as usual by ctr.
4) link: whenever a hardlink is created for the inode, we create the inode context
variable, if not present, and add the hardlink to the list.
5) unlink: whenever a unlink happens we delete the hardlink from the list.
6) mknod: same as create.
7) rename: whenever a rename happens we update the hardlink in list. if the hardlink
was not present for updation, we add the hardlink to the list.
What is pending:
1) This solution will only work for named lookups.
2) We dont track afr-self-heal/dht-rebalancer traffic for healing.
Change-Id: Ia4bbaf84128ad6ce8c3ddd70bcfa82894c79585f
BUG: 1212037
Signed-off-by: Joseph Fernandes <josferna@redhat.com>
Signed-off-by: Dan Lambright <dlambrig@redhat.com>
Reviewed-on: http://review.gluster.org/10370
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Tested-by: NetBSD Build System
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/features/changetimerecorder/src/ctr-helper.h')
-rw-r--r-- | xlators/features/changetimerecorder/src/ctr-helper.h | 143 |
1 files changed, 142 insertions, 1 deletions
diff --git a/xlators/features/changetimerecorder/src/ctr-helper.h b/xlators/features/changetimerecorder/src/ctr-helper.h index 85ee872fa3..87b80e6035 100644 --- a/xlators/features/changetimerecorder/src/ctr-helper.h +++ b/xlators/features/changetimerecorder/src/ctr-helper.h @@ -28,6 +28,7 @@ #include <sys/time.h> #include "gfdb_data_store.h" +#include "ctr-xlator-ctx.h" /*CTR Xlator Private structure*/ typedef struct gf_ctr_private { @@ -384,7 +385,7 @@ ctr_insert_wind (call_frame_t *frame, /*Insert the db record*/ ret = insert_record (_priv->_db_conn, - &ctr_local->gfdb_db_record); + &ctr_local->gfdb_db_record); if (ret) { gf_log (this->name, GF_LOG_ERROR, "WIND: Inserting of record failed!"); @@ -462,6 +463,146 @@ out: return ret; } +/******************************* Hard link function ***************************/ + +static inline int +add_hard_link_ctx (call_frame_t *frame, + xlator_t *this, + inode_t *inode) +{ + int ret = -1; + gf_ctr_local_t *ctr_local = NULL; + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; + ctr_hard_link_t *ctr_hard_link = NULL; + + GF_ASSERT (frame); + GF_ASSERT (this); + GF_ASSERT (inode); + + ctr_local = frame->local; + if (!ctr_local) { + goto out; + } + + ctr_xlator_ctx = init_ctr_xlator_ctx (this, inode); + if (!ctr_xlator_ctx) { + gf_log (this->name, GF_LOG_ERROR, + "Failed accessing ctr inode context"); + goto out; + } + + LOCK (&ctr_xlator_ctx->lock); + + /* Check if the hard link already exists + * in the ctr inode context*/ + ctr_hard_link = ctr_search_hard_link_ctx (this, + ctr_xlator_ctx, + CTR_DB_REC(ctr_local).pargfid, + CTR_DB_REC(ctr_local).file_name); + /* if there then ignore */ + if (ctr_hard_link) { + ret = 1; + goto unlock; + } + + /* Add the hard link to the list*/ + ret = ctr_add_hard_link (this, ctr_xlator_ctx, + CTR_DB_REC(ctr_local).pargfid, + CTR_DB_REC(ctr_local).file_name); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to add hardlink to the ctr inode context"); + goto unlock; + } + + ret = 0; +unlock: + UNLOCK (&ctr_xlator_ctx->lock); +out: + return ret; +} + +static inline int +delete_hard_link_ctx (call_frame_t *frame, + xlator_t *this, + inode_t *inode) +{ + int ret = -1; + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; + gf_ctr_local_t *ctr_local = NULL; + + GF_ASSERT (frame); + GF_ASSERT (this); + GF_ASSERT (inode); + + ctr_local = frame->local; + if (!ctr_local) { + goto out; + } + + ctr_xlator_ctx = get_ctr_xlator_ctx (this, inode); + if (!ctr_xlator_ctx) { + /* Since there is no ctr inode context so nothing more to do */ + ret = 0; + goto out; + } + + ret = ctr_delete_hard_link (this, ctr_xlator_ctx, + CTR_DB_REC(ctr_local).pargfid, + CTR_DB_REC(ctr_local).file_name); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to delete hard link"); + goto out; + } + + ret = 0; + +out: + return ret; +} + +static inline int +update_hard_link_ctx (call_frame_t *frame, + xlator_t *this, + inode_t *inode) +{ + int ret = -1; + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; + gf_ctr_local_t *ctr_local = NULL; + + GF_ASSERT (frame); + GF_ASSERT (this); + GF_ASSERT (inode); + + ctr_local = frame->local; + if (!ctr_local) { + goto out; + } + + ctr_xlator_ctx = init_ctr_xlator_ctx (this, inode); + if (!ctr_xlator_ctx) { + gf_log (this->name, GF_LOG_ERROR, + "Failed accessing ctr inode context"); + goto out; + } + + ret = ctr_update_hard_link (this, ctr_xlator_ctx, + CTR_DB_REC(ctr_local).pargfid, + CTR_DB_REC(ctr_local).file_name, + CTR_DB_REC(ctr_local).old_pargfid, + CTR_DB_REC(ctr_local).old_file_name); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to delete hard link"); + goto out; + } + + ret = 0; + +out: + return ret; +} + + /****************************************************************************** * * CTR xlator init related functions |