diff options
| -rw-r--r-- | libglusterfs/src/common-utils.h | 3 | ||||
| -rwxr-xr-x | tests/features/trash.t | 20 | ||||
| -rw-r--r-- | xlators/features/trash/src/trash.c | 20 | ||||
| -rw-r--r-- | xlators/features/trash/src/trash.h | 21 | 
4 files changed, 48 insertions, 16 deletions
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index a35ea16b972..edd198cadc0 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -131,7 +131,8 @@ enum _gf_special_pid          GF_CLIENT_PID_GLFS_HEAL         = -7,          GF_CLIENT_PID_BITD              = -8,          GF_CLIENT_PID_SCRUB             = -9, -        GF_CLIENT_PID_TIER_DEFRAG       = -10 +        GF_CLIENT_PID_TIER_DEFRAG       = -10, +        GF_SERVER_PID_TRASH             = -11  };  enum _gf_xlator_ipc_targets { diff --git a/tests/features/trash.t b/tests/features/trash.t index 268baac570f..620b84f0da1 100755 --- a/tests/features/trash.t +++ b/tests/features/trash.t @@ -93,11 +93,6 @@ wildcard_not_exists() {          if [ $? -eq 0 ]; then echo "Y"; else echo "N"; fi  } -heal_ready() { -        $CLI volume heal $1 info | grep -q '^Brick' -        if [ $? -eq 0 ]; then echo "Y"; else echo "N"; fi -} -  # testing glusterd [1-3]  TEST glusterd  TEST pidof glusterd @@ -227,26 +222,23 @@ EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "1" online_brick_count  rm -f $M1/self  EXPECT "Y" wildcard_exists $B0/${V1}2/.trashcan/self* -# force start the volume and trigger the self-heal manually [55-59] +# force start the volume and trigger the self-heal manually [55-57]  TEST $CLI volume start $V1 force  EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" online_brick_count  EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status -# volume heal one sometimes fail with "Launching heal operation to -# perform index self heal on volume patchy1 has been unsuccessful" -# Hence firt check heal is really functionnal. -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" heal_ready $V1 -TEST $CLI volume heal $V1 +# Since we created the file under root of the volume, it will be +# healed automatically -# check for the removed file in trashcan [60] +# check for the removed file in trashcan [58]  EXPECT_WITHIN $HEAL_TIMEOUT "Y" wildcard_exists $B0/${V1}1/.trashcan/internal_op/self* -# check renaming of trash directory through cli [61-64] +# check renaming of trash directory through cli [59-62]  TEST $CLI volume set $V0 trash-dir abc  TEST start_vol $V0 $M0 $M0/abc  TEST [ -e $M0/abc -a ! -e $M0/.trashcan ]  EXPECT "Y" wildcard_exists $B0/${V0}1/abc/internal_op/rebal2* -# ensure that rename and delete operation on trash directory fails [65-67] +# ensure that rename and delete operation on trash directory fails [63-65]  rm -rf $M0/abc/internal_op  TEST [ -e $M0/abc/internal_op ]  rm -rf $M0/abc/ diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c index 4b0e6741d9a..025d2c2efc1 100644 --- a/xlators/features/trash/src/trash.c +++ b/xlators/features/trash/src/trash.c @@ -598,6 +598,8 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          local   = frame->local;          GF_VALIDATE_OR_GOTO ("trash", local, out); +        TRASH_UNSET_PID (frame, local); +          tmp_str = gf_strdup (local->newpath);          if (!tmp_str) {                  gf_log (this->name, GF_LOG_ERROR, "out of memory"); @@ -645,6 +647,9 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  remove_trash_path (tmp_path, (frame->root->pid < 0), &tmp_stat);                  if (tmp_stat)                          strcat (real_path, tmp_stat); + +                TRASH_SET_PID (frame, local); +                  STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_path,                                     FIRST_CHILD(this),                                     FIRST_CHILD(this)->fops->mkdir, @@ -727,6 +732,8 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (tmp_stat)                  strcat (real_path, tmp_stat); +        TRASH_SET_PID (frame, local); +          STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_path,                             FIRST_CHILD(this),                             FIRST_CHILD(this)->fops->mkdir, &tmp_loc, @@ -798,6 +805,9 @@ trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  remove_trash_path (tmp_str, (frame->root->pid < 0), &tmp_stat);                  if (tmp_stat)                          strcat (real_path, tmp_stat); + +                TRASH_SET_PID (frame, local); +                  /* create the directory with proper permissions */                  STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_cookie,                                     FIRST_CHILD(this), @@ -1317,6 +1327,9 @@ trash_truncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  remove_trash_path (tmp_path, (frame->root->pid < 0), &tmp_stat);                  if (tmp_stat)                          strcat (real_path, tmp_stat); + +                TRASH_SET_PID (frame, local); +                  /* create the directory with proper permissions */                  STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk,                                     tmp_path, FIRST_CHILD(this), @@ -1395,6 +1408,8 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          loop_count = local->loop_count; +        TRASH_UNSET_PID (frame, local); +          tmp_str = gf_strdup (local->newpath);          if (!tmp_str) {                  gf_log (this->name, GF_LOG_DEBUG, "out of memory"); @@ -1440,6 +1455,9 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  remove_trash_path (tmp_path, (frame->root->pid < 0), &tmp_stat);                  if (tmp_stat)                          strcat (real_path, tmp_stat); + +                TRASH_SET_PID (frame, local); +                  STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk,                                     tmp_path, FIRST_CHILD(this),                                     FIRST_CHILD(this)->fops->mkdir, @@ -1523,6 +1541,8 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (tmp_stat)                  strcat (real_path, tmp_stat); +        TRASH_SET_PID (frame, local); +          STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk, tmp_path,                             FIRST_CHILD(this),                             FIRST_CHILD(this)->fops->mkdir, &tmp_loc, diff --git a/xlators/features/trash/src/trash.h b/xlators/features/trash/src/trash.h index 9a57ac9f67e..088c1b9a286 100644 --- a/xlators/features/trash/src/trash.h +++ b/xlators/features/trash/src/trash.h @@ -39,10 +39,12 @@ struct trash_struct {          loc_t    newloc;     /* to store the location for the new file */          size_t   fsize;      /* for keeping the size of existing file */          off_t    cur_offset; /* current offset for read and write ops */ -        off_t    fop_offset; +        off_t    fop_offset; /* original offset received with the fop */ +        pid_t    pid;          char     origpath[PATH_MAX];          char     newpath[PATH_MAX];          int32_t  loop_count; +        gf_boolean_t is_set_pid;          struct iatt preparent;          struct iatt postparent;          gf_boolean_t ctr_link_count_req; @@ -68,6 +70,23 @@ struct trash_priv {  };  typedef struct trash_priv trash_private_t; +#define TRASH_SET_PID(frame, local) do {                        \ +                GF_ASSERT (!local->is_set_pid);                 \ +                if (!local->is_set_pid) {                       \ +                        local->pid = frame->root->pid;          \ +                        frame->root->pid = GF_SERVER_PID_TRASH; \ +                        local->is_set_pid = _gf_true;           \ +                }                                               \ +} while (0) + +#define TRASH_UNSET_PID(frame, local) do {              \ +                GF_ASSERT (local->is_set_pid);          \ +                if (local->is_set_pid) {                \ +                        frame->root->pid = local->pid;  \ +                        local->is_set_pid = _gf_false;  \ +                }                                       \ +} while (0) +  #define TRASH_STACK_UNWIND(op, frame, params ...) do {    \                  trash_local_t *__local = NULL;            \                  __local = frame->local;                   \  | 
