diff options
-rw-r--r-- | libglusterfs/src/gfdb/gfdb_data_store_types.h | 11 | ||||
-rwxr-xr-x | tests/basic/tier/ctr-rename-overwrite.t | 49 | ||||
-rw-r--r-- | xlators/features/changetimerecorder/src/changetimerecorder.c | 185 | ||||
-rw-r--r-- | xlators/features/changetimerecorder/src/ctr-helper.c | 9 | ||||
-rw-r--r-- | xlators/features/changetimerecorder/src/ctr-helper.h | 141 |
5 files changed, 371 insertions, 24 deletions
diff --git a/libglusterfs/src/gfdb/gfdb_data_store_types.h b/libglusterfs/src/gfdb/gfdb_data_store_types.h index ce09e731746..d79bf41a8c9 100644 --- a/libglusterfs/src/gfdb/gfdb_data_store_types.h +++ b/libglusterfs/src/gfdb/gfdb_data_store_types.h @@ -268,13 +268,20 @@ isdentrycreatefop(gfdb_fop_type_t fop_type) /*The structure that is used to send insert/update the databases * using insert_db api*/ typedef struct gfdb_db_record { + /* GFID */ uuid_t gfid; + /* Used during a rename refer ctr_rename() in changetimerecorder + * xlator*/ + uuid_t old_gfid; + /* Parent GFID */ uuid_t pargfid; uuid_t old_pargfid; - char file_name[PATH_MAX]; + /* File names and paths */ + char file_name[GF_NAME_MAX]; char file_path[PATH_MAX]; - char old_file_name[PATH_MAX]; + char old_file_name[GF_NAME_MAX]; char old_path[PATH_MAX]; + /* FOP type and FOP path*/ gfdb_fop_type_t gfdb_fop_type; gfdb_fop_path_t gfdb_fop_path; /*Time of change or access*/ diff --git a/tests/basic/tier/ctr-rename-overwrite.t b/tests/basic/tier/ctr-rename-overwrite.t new file mode 100755 index 00000000000..a1d5af03a39 --- /dev/null +++ b/tests/basic/tier/ctr-rename-overwrite.t @@ -0,0 +1,49 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../tier.rc + +LAST_BRICK=1 +CACHE_BRICK_FIRST=4 +CACHE_BRICK_LAST=5 + +DEMOTE_FREQ=5 +PROMOTE_FREQ=5 + +cleanup + +# Start glusterd +TEST glusterd +TEST pidof glusterd + +# Set-up tier cluster +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..$LAST_BRICK} +TEST $CLI volume start $V0 +TEST $CLI volume attach-tier $V0 replica 2 $H0:$B0/${V0}$CACHE_BRICK_FIRST $H0:$B0/${V0}$CACHE_BRICK_LAST + +TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ +TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ + +# Start and mount the volume after enabling CTR +TEST $CLI volume set $V0 features.ctr-enabled on +TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0; + +# create two files +echo "hello world" > $M0/file1 +echo "hello world" > $M0/file2 + +# db in hot brick shows 4 record. 2 for file1 and 2 for file2 +ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \ + sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l ) +TEST [ $ENTRY_COUNT -eq 4 ] + +#overwrite file2 with file1 +mv -f $M0/file1 $M0/file2 + +# Now the db in hot tier should have only 2 records for file1. +ENTRY_COUNT=$(echo "select * from gf_file_tb; select * from gf_flink_tb;" | \ + sqlite3 $B0/${V0}5/.glusterfs/${V0}5.db | wc -l ) +TEST [ $ENTRY_COUNT -eq 2 ] + +cleanup diff --git a/xlators/features/changetimerecorder/src/changetimerecorder.c b/xlators/features/changetimerecorder/src/changetimerecorder.c index 242fb2b51fc..2c05d07dcb7 100644 --- a/xlators/features/changetimerecorder/src/changetimerecorder.c +++ b/xlators/features/changetimerecorder/src/changetimerecorder.c @@ -374,9 +374,10 @@ ctr_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, { int ret = -1; - CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IS_DISABLED_THEN_GOTO (this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); - ret = ctr_insert_unwind(frame, this, + ret = ctr_insert_unwind (frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, @@ -386,6 +387,8 @@ ctr_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); @@ -438,6 +441,7 @@ ctr_setattr_cbk (call_frame_t *frame, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); @@ -448,6 +452,8 @@ ctr_setattr_cbk (call_frame_t *frame, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop_stbuf, postop_stbuf, xdata); @@ -499,6 +505,7 @@ ctr_fsetattr_cbk (call_frame_t *frame, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); @@ -509,6 +516,8 @@ ctr_fsetattr_cbk (call_frame_t *frame, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, preop_stbuf, postop_stbuf, xdata); @@ -557,7 +566,7 @@ ctr_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); - + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); @@ -568,6 +577,8 @@ ctr_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata); return 0; @@ -614,6 +625,7 @@ ctr_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); CTR_IF_INTERNAL_FOP_THEN_GOTO (frame, xdata, out); @@ -626,6 +638,8 @@ ctr_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata); return 0; @@ -673,7 +687,7 @@ ctr_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); - + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); @@ -685,6 +699,8 @@ ctr_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); @@ -731,6 +747,7 @@ ctr_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); @@ -741,6 +758,8 @@ ctr_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); @@ -779,7 +798,6 @@ out: } /****************************rename******************************************/ - int32_t ctr_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, @@ -787,19 +805,78 @@ ctr_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { - int ret = -1; + int ret = -1; + uint32_t remaining_links = -1; + gf_ctr_local_t *ctr_local = NULL; + gfdb_fop_type_t fop_type = GFDB_FOP_INVALID_OP; + gfdb_fop_path_t fop_path = GFDB_FOP_INVALID; - CTR_IS_DISABLED_THEN_GOTO(this, out); + GF_ASSERT(frame); + GF_ASSERT(this); - ret = ctr_insert_unwind(frame, this, + CTR_IS_DISABLED_THEN_GOTO (this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); + + ret = ctr_insert_unwind (frame, this, GFDB_FOP_DENTRY_WRITE, GFDB_FOP_UNWIND); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_RENAME_UNWIND_FAILED, "Failed to insert rename unwind"); + goto out; + } + + if (!xdata) + goto out; + /* + * + * Extracting GF_RESPONSE_LINK_COUNT_XDATA from POSIX Xlator + * This is only set when we are overwriting hardlinks. + * + * */ + ret = dict_get_uint32 (xdata , GF_RESPONSE_LINK_COUNT_XDATA, + &remaining_links); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + CTR_MSG_GET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, + "Failed to getting GF_RESPONSE_LINK_COUNT_XDATA"); + remaining_links = -1; + goto out; + } + + ctr_local = frame->local; + + /* This is not the only link */ + if (remaining_links > 1) { + fop_type = GFDB_FOP_DENTRY_WRITE; + fop_path = GFDB_FOP_UNDEL; + } + /* Last link that was deleted */ + else if (remaining_links == 1) { + fop_type = GFDB_FOP_DENTRY_WRITE; + fop_path = GFDB_FOP_UNDEL_ALL; + } else { + gf_msg (this->name, GF_LOG_ERROR, 0, + CTR_MSG_INSERT_RENAME_UNWIND_FAILED, + "Invalid link count from posix"); + goto out; + } + + ret = ctr_delete_hard_link_from_db (this, + CTR_DB_REC(ctr_local).old_gfid, + CTR_DB_REC(ctr_local).pargfid, + CTR_DB_REC(ctr_local).file_name, + fop_type, fop_path); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + CTR_MSG_INSERT_UNLINK_UNWIND_FAILED, + "Failed to delete records of %s", + CTR_DB_REC(ctr_local).old_file_name); } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, @@ -812,12 +889,14 @@ int32_t ctr_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { - int ret = -1; + int ret = -1; gf_ctr_inode_context_t ctr_inode_cx; - gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; + gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; gf_ctr_link_context_t new_link_cx, old_link_cx; - gf_ctr_link_context_t *_nlink_cx = &new_link_cx; - gf_ctr_link_context_t *_olink_cx = &old_link_cx; + gf_ctr_link_context_t *_nlink_cx = &new_link_cx; + gf_ctr_link_context_t *_olink_cx = &old_link_cx; + int is_dict_created = 0; + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; CTR_IS_DISABLED_THEN_GOTO(this, out); CTR_IF_INTERNAL_FOP_THEN_GOTO (frame, xdata, out); @@ -835,6 +914,20 @@ ctr_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, oldloc->inode->gfid, _nlink_cx, _olink_cx, GFDB_FOP_DENTRY_WRITE, GFDB_FOP_WIND); + + /* If the rename is a overwrite of hardlink + * rename ("file1", "file2") + * file1 is hardlink for gfid say 00000000-0000-0000-0000-00000000000A + * file2 is hardlink for gfid say 00000000-0000-0000-0000-00000000000B + * so we are saving file2 gfid in old_gfid so that we delete entries + * from the db during rename callback if the fop is successful + * */ + if (newloc->inode) { + /* This is the GFID from where the newloc hardlink will be + * unlinked */ + _inode_cx->old_gfid = &newloc->inode->gfid; + } + /* Is a metatdata fop */ _inode_cx->is_metadata_fop = _gf_true; @@ -852,6 +945,45 @@ ctr_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_UPDATE_HARDLINK_FAILED, "Failed " "updating hard link in ctr inode context"); + goto out; + } + + /* If the newloc has an inode. i.e aquiring hardlink of an + * exisitng file i.e overwritting a file. + * */ + if (newloc->inode) { + + /* Getting the ctr inode context variable for + * inode whose hardlink will be aquired during + * the rename + * */ + ctr_xlator_ctx = get_ctr_xlator_ctx (this, + newloc->inode); + if (!ctr_xlator_ctx) { + /* Since there is no ctr inode context + * so nothing more to do */ + ret = 0; + goto out; + } + + /* Deleting hardlink from context variable */ + ret = ctr_delete_hard_link (this, ctr_xlator_ctx, + newloc->pargfid, newloc->name); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + CTR_MSG_DELETE_HARDLINK_FAILED, + "Failed to delete hard link"); + goto out; + } + + /* Requesting for number of hardlinks on the newloc + * inode from POSIX. + * */ + is_dict_created = set_posix_link_request (this, &xdata); + if (is_dict_created == -1) { + ret = -1; + goto out; + } } } @@ -859,6 +991,11 @@ out: STACK_WIND (frame, ctr_rename_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->rename, oldloc, newloc, xdata); + + if (is_dict_created == 1) { + dict_unref (xdata); + } + return 0; } @@ -872,6 +1009,7 @@ ctr_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, uint32_t remaining_links = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); if (!xdata) goto out; @@ -914,6 +1052,8 @@ ctr_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent, postparent, xdata); @@ -1022,6 +1162,7 @@ ctr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); @@ -1032,6 +1173,8 @@ ctr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); @@ -1088,6 +1231,8 @@ ctr_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata); return 0; @@ -1133,6 +1278,7 @@ ctr_fsetxattr_cbk (call_frame_t *frame, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); @@ -1143,6 +1289,8 @@ ctr_fsetxattr_cbk (call_frame_t *frame, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata); return 0; @@ -1192,6 +1340,7 @@ ctr_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, ctr_heal_ret_val_t ret_val = CTR_CTX_ERROR; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); /* Add hard link to the list */ ret_val = add_hard_link_ctx (frame, this, inode); @@ -1208,6 +1357,8 @@ ctr_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); @@ -1276,7 +1427,7 @@ ctr_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); - + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = add_hard_link_ctx (frame, this, inode); if (ret) { @@ -1294,6 +1445,8 @@ ctr_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); @@ -1373,6 +1526,7 @@ ctr_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); /* Add hard link to the list */ ret = add_hard_link_ctx (frame, this, inode); @@ -1389,6 +1543,8 @@ ctr_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; @@ -1456,6 +1612,7 @@ int ctr_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; CTR_IS_DISABLED_THEN_GOTO(this, out); + CTR_IF_FOP_FAILED_THEN_GOTO (this, op_ret, op_errno, out); ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_READ, GFDB_FOP_UNWIND); @@ -1466,6 +1623,8 @@ int ctr_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + ctr_free_frame_local (frame); + STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); return 0; diff --git a/xlators/features/changetimerecorder/src/ctr-helper.c b/xlators/features/changetimerecorder/src/ctr-helper.c index ab918eac825..ba48a70f583 100644 --- a/xlators/features/changetimerecorder/src/ctr-helper.c +++ b/xlators/features/changetimerecorder/src/ctr-helper.c @@ -120,9 +120,16 @@ fill_db_record_for_wind (xlator_t *this, memset(ctr_wtime, 0, sizeof(*ctr_wtime)); } - /*Copy gfid into db record*/ + /* Copy gfid into db record */ gf_uuid_copy (CTR_DB_REC(ctr_local).gfid, *(ctr_inode_cx->gfid)); + /* Copy older gfid if any */ + if (ctr_inode_cx->old_gfid && + (!gf_uuid_is_null (*(ctr_inode_cx->old_gfid)))) { + gf_uuid_copy (CTR_DB_REC(ctr_local).old_gfid, + *(ctr_inode_cx->old_gfid)); + } + /*Hard Links*/ if (isdentryfop(ctr_inode_cx->fop_type)) { /*new link fop*/ diff --git a/xlators/features/changetimerecorder/src/ctr-helper.h b/xlators/features/changetimerecorder/src/ctr-helper.h index 6ddc5b8ca19..025965898d2 100644 --- a/xlators/features/changetimerecorder/src/ctr-helper.h +++ b/xlators/features/changetimerecorder/src/ctr-helper.h @@ -167,6 +167,7 @@ typedef struct gf_ctr_link_context { typedef struct gf_ctr_inode_context { ia_type_t ia_type; uuid_t *gfid; + uuid_t *old_gfid; gf_ctr_link_context_t *new_link_cx; gf_ctr_link_context_t *old_link_cx; gfdb_fop_type_t fop_type; @@ -230,10 +231,10 @@ do {\ _fop_type,\ _fop_path)\ do {\ - GF_ASSERT(ctr_inode_cx);\ - GF_ASSERT(_gfid);\ - GF_ASSERT(_fop_type != GFDB_FOP_INVALID_OP);\ - GF_ASSERT(_fop_path != GFDB_FOP_INVALID);\ + GF_ASSERT (ctr_inode_cx);\ + GF_ASSERT (_gfid);\ + GF_ASSERT (_fop_type != GFDB_FOP_INVALID_OP);\ + GF_ASSERT (_fop_path != GFDB_FOP_INVALID);\ memset(ctr_inode_cx, 0, sizeof(*ctr_inode_cx));\ ctr_inode_cx->ia_type = _ia_type;\ ctr_inode_cx->gfid = &_gfid;\ @@ -247,12 +248,74 @@ do {\ ctr_inode_cx->fop_path = _fop_path;\ } while (0) + /****************************************************************************** * * Util functions or macros used by * insert wind and insert unwind * * ****************************************************************************/ +/* Free ctr frame local */ +static inline void +ctr_free_frame_local (call_frame_t *frame) { + if (frame) { + free_ctr_local ((gf_ctr_local_t *) frame->local); + frame->local = NULL; + } +} + +/* Setting GF_REQUEST_LINK_COUNT_XDATA in dict + * that has to be sent to POSIX Xlator to send + * link count in unwind path. + * return 0 for success with not creation of dict + * return 1 for success with creation of dict + * return -1 for failure. + * */ +static inline int +set_posix_link_request (xlator_t *this, + dict_t **xdata) +{ + int ret = -1; + gf_boolean_t is_created = _gf_false; + + GF_VALIDATE_OR_GOTO ("ctr", this, out); + GF_VALIDATE_OR_GOTO (this->name, xdata, out); + + /*create xdata if NULL*/ + if (!*xdata) { + *xdata = dict_new(); + is_created = _gf_true; + ret = 1; + } else { + ret = 0; + } + + if (!*xdata) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_XDATA_NULL, + "xdata is NULL :Cannot send " + "GF_REQUEST_LINK_COUNT_XDATA to posix"); + ret = -1; + goto out; + } + + ret = dict_set_int32 (*xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + CTR_MSG_SET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, + "Failed setting GF_REQUEST_LINK_COUNT_XDATA"); + ret = -1; + goto out; + } + ret = 0; +out: + if (ret == -1) { + if (*xdata && is_created) { + dict_unref (*xdata); + } + } + return ret; +} + /* * If a bitrot fop @@ -293,8 +356,8 @@ do {\ * Internal fop * * */ -static inline -gf_boolean_t is_internal_fop (call_frame_t *frame, +static inline gf_boolean_t +is_internal_fop (call_frame_t *frame, dict_t *xdata) { gf_boolean_t ret = _gf_false; @@ -327,6 +390,15 @@ do {\ goto label; \ } while (0) +/* if fop has failed exit */ +#define CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, label)\ +do {\ + if (op_ret == -1) {\ + gf_msg_trace (this->name, 0, "Failed fop with %s",\ + strerror (op_errno));\ + goto label;\ + };\ +} while (0) /* * IS CTR Xlator is disabled then goto to label @@ -372,6 +444,7 @@ fill_db_record_for_wind (xlator_t *this, * This function creates ctr_local structure into the frame of the fop * call. * ****************************************************************************/ + static inline int ctr_insert_wind (call_frame_t *frame, xlator_t *this, @@ -538,8 +611,60 @@ ctr_insert_unwind (call_frame_t *frame, } ret = 0; out: - free_ctr_local (ctr_local); - frame->local = NULL; + return ret; +} + +/****************************************************************************** + * Delete file/flink record/s from db + * ****************************************************************************/ +static inline int +ctr_delete_hard_link_from_db (xlator_t *this, + uuid_t gfid, + uuid_t pargfid, + char *basename, + gfdb_fop_type_t fop_type, + gfdb_fop_path_t fop_path) +{ + int ret = -1; + gfdb_db_record_t gfdb_db_record; + gf_ctr_private_t *_priv = NULL; + + _priv = this->private; + GF_VALIDATE_OR_GOTO (this->name, _priv, out); + GF_VALIDATE_OR_GOTO (this->name, (!gf_uuid_is_null (gfid)), out); + GF_VALIDATE_OR_GOTO (this->name, (!gf_uuid_is_null (pargfid)), out); + GF_VALIDATE_OR_GOTO (this->name, (fop_type == GFDB_FOP_DENTRY_WRITE), + out); + GF_VALIDATE_OR_GOTO (this->name, + (fop_path == GFDB_FOP_UNDEL || GFDB_FOP_UNDEL_ALL), + out); + + /* Set gfdb_db_record to 0 */ + memset (&gfdb_db_record, 0, sizeof(gfdb_db_record)); + + /* Copy gfid into db record */ + gf_uuid_copy (gfdb_db_record.gfid, gfid); + + /* Copy pargid into db record */ + gf_uuid_copy (gfdb_db_record.pargfid, pargfid); + + /* Copy basename */ + strncpy (gfdb_db_record.file_name, basename, GF_NAME_MAX - 1); + + gfdb_db_record.gfdb_fop_path = fop_path; + gfdb_db_record.gfdb_fop_type = fop_type; + + /*send delete request to db*/ + ret = insert_record (_priv->_db_conn, &gfdb_db_record); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + CTR_MSG_INSERT_RECORD_WIND_FAILED, + "Failed to delete record. %s", basename); + goto out; + } + + ret = 0; +out: return ret; } |