diff options
author | Anoop C S <anoopcs@redhat.com> | 2016-03-18 10:32:09 +0530 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2016-04-27 14:24:48 -0700 |
commit | b5cfe948cb3569f034da80ac97b5d2f028b3b0e5 (patch) | |
tree | 98e2b6a8c040d22701aea89c7446abd789282e05 /xlators | |
parent | c4d67a8338b42d6485f49999f310cbb9ed5359c5 (diff) |
features/trash: wind mkdir with special pid
Recent changes done w.r.t handling of mkdir calls in posix translator
resulted in crashing the brick process from trash translator. This was
due to the changes made in posix translator to return EPERM for every
mkdir calls without 'gfid-req' set in dictionary. In order to avoid
gfid mismatches during directory creation from brick side trash
translator does not set 'gfid-req'. This patch is to have an exemption
for trash based on a special pid set for those mkdir calls originating
from trash translator and to reset it in callback.
This patch also includes a small optimization to the existing test case
for trash feature.
Change-Id: I59f084ac875e54342ecf2bffa6e43ebd84814153
BUG: 1317361
Signed-off-by: Anoop C S <anoopcs@redhat.com>
Reviewed-on: http://review.gluster.org/13776
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/trash/src/trash.c | 20 | ||||
-rw-r--r-- | xlators/features/trash/src/trash.h | 21 |
2 files changed, 40 insertions, 1 deletions
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; \ |