diff options
| author | shishir gowda <sgowda@redhat.com> | 2013-05-16 19:32:49 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2013-05-16 08:49:39 -0700 | 
| commit | 1a7e6053d3842761f946fbbdd693c72aa3945a97 (patch) | |
| tree | fe459937358109e966a5ac615adbeb590a359119 | |
| parent | ddc0b45c4d4826e86500740f672892eeb28ab325 (diff) | |
cluster/dht: Linkfiles creation with correct uid/gidv3.3.2qa3
If renames are done with different uid/gid (non-owners), then we would
end up with incorrect uid/gid.
The fix is to create linkfiles, and heal the uid/gid as root:root. This
preserves our notion of creation as root:root and heal the uid/gid as
root:root in all paths. Additionally, we need to consider uid/gid from
only src_cached subvol, and not from linkfiles.
rename is also done as root:root if done on linkfile, as setattr of ownership
on linkfile is done after the rename
BUG: 884597
Change-Id: Ifaacd8dba0f39cb909761ffc8fe7e06cd44ec8de
Signed-off-by: shishir gowda <sgowda@redhat.com>
Reviewed-on: http://review.gluster.org/5025
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | xlators/cluster/dht/src/dht-linkfile.c | 7 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-rename.c | 60 | 
2 files changed, 47 insertions, 20 deletions
diff --git a/xlators/cluster/dht/src/dht-linkfile.c b/xlators/cluster/dht/src/dht-linkfile.c index 67d6ce583a9..9de3703410a 100644 --- a/xlators/cluster/dht/src/dht-linkfile.c +++ b/xlators/cluster/dht/src/dht-linkfile.c @@ -34,6 +34,8 @@ dht_linkfile_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (!op_ret)                  local->linked = _gf_true; +        FRAME_SU_UNDO (frame, dht_local_t); +          local->linkfile.linkfile_cbk (frame, cookie, this, op_ret, op_errno,                                        inode, stbuf, preparent, postparent,                                        xdata); @@ -87,6 +89,9 @@ dht_linkfile_create (call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk,          }          local->link_subvol = fromvol; +        /* Always create as root:root. dht_linkfile_attr_heal fixes the +         * ownsership */ +        FRAME_SU_DO (frame, dht_local_t);          STACK_WIND (frame, dht_linkfile_create_cbk,                      fromvol, fromvol->fops->mknod, loc,                      S_IFREG | DHT_LINKFILE_MODE, 0, 0, dict); @@ -252,6 +257,8 @@ dht_linkfile_attr_heal (call_frame_t *frame, xlator_t *this)          copy->local = copy_local; +        FRAME_SU_DO (copy, dht_local_t); +          STACK_WIND (copy, dht_linkfile_setattr_cbk, subvol,                      subvol->fops->setattr, ©_local->loc,                      &stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID), NULL); diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c index 35fedeaa7a4..f0eecb2d7ab 100644 --- a/xlators/cluster/dht/src/dht-rename.c +++ b/xlators/cluster/dht/src/dht-rename.c @@ -307,6 +307,25 @@ err:          return 0;  } +int +dht_rename_done (call_frame_t *frame, xlator_t *this) +{ +        dht_local_t     *local = NULL; + +        local = frame->local; + +        if (local->linked == _gf_true) { +                local->linked = _gf_false; +                dht_linkfile_attr_heal (frame, this); +        } +        DHT_STRIP_PHASE1_FLAGS (&local->stbuf); +        DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno, +                          &local->stbuf, &local->preoldparent, +                          &local->postoldparent, &local->preparent, +                          &local->postparent, NULL); + +        return 0; +}  int  dht_rename_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -340,11 +359,7 @@ dht_rename_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          WIPE (&local->postparent);          if (is_last_call (this_call_cnt)) { -                DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -                DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno, -                                  &local->stbuf, &local->preoldparent, -                                  &local->postoldparent, &local->preparent, -                                  &local->postparent, NULL); +                dht_rename_done (frame, this);          }  out: @@ -476,6 +491,8 @@ dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          dst_hashed = local->dst_hashed;          dst_cached = local->dst_cached; +        if (local->linked == _gf_true) +                FRAME_SU_UNDO (frame, dht_local_t);          if (op_ret == -1) {                  gf_log (this->name, GF_LOG_WARNING,                          "%s: rename on %s failed (%s)", local->loc.path, @@ -509,17 +526,21 @@ dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          }  err: -        dht_iatt_merge (this, &local->stbuf, stbuf, prev->this); -        dht_iatt_merge (this, &local->preoldparent, preoldparent, prev->this); -        dht_iatt_merge (this, &local->postoldparent, postoldparent, prev->this); -        dht_iatt_merge (this, &local->preparent, prenewparent, prev->this); -        dht_iatt_merge (this, &local->postparent, postnewparent, prev->this); - -        if (local->linked == _gf_true) { -                local->linked = _gf_false; -                dht_linkfile_attr_heal (frame, this); +        /* Merge attrs only from src_cached. In case there of src_cached != +         * dst_hashed, this ignores linkfile attrs. */ +        if (prev->this == src_cached) { +                dht_iatt_merge (this, &local->stbuf, stbuf, prev->this); +                dht_iatt_merge (this, &local->preoldparent, preoldparent, +                                prev->this); +                dht_iatt_merge (this, &local->postoldparent, postoldparent, +                                prev->this); +                dht_iatt_merge (this, &local->preparent, prenewparent, +                                prev->this); +                dht_iatt_merge (this, &local->postparent, postnewparent, +                                prev->this);          } +          /* NOTE: rename_subvol is the same subvolume from which dht_rename_cbk           *       is called. since rename has already happened on rename_subvol,           *       unlink should not be sent for oldpath (either linkfile or cached-file) @@ -582,11 +603,7 @@ unwind:          WIPE (&local->preparent);          WIPE (&local->postparent); -        DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -        DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno, -                          &local->stbuf, &local->preoldparent, -                          &local->postoldparent, &local->preparent, -                          &local->postparent, NULL); +        dht_rename_done (frame, this);          return 0; @@ -624,6 +641,8 @@ dht_do_rename (call_frame_t *frame)                  "renaming %s => %s (%s)",                  local->loc.path, local->loc2.path, rename_subvol->name); +        if (local->linked == _gf_true) +                FRAME_SU_DO (frame, dht_local_t);          STACK_WIND (frame, dht_rename_cbk,                      rename_subvol, rename_subvol->fops->rename,                      &local->loc, &local->loc2, NULL); @@ -654,7 +673,8 @@ dht_rename_links_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  local->op_ret   = -1;                  if (op_errno != ENOENT)                          local->op_errno = op_errno; -        } else { +        } else if (local->src_cached == prev->this) { +                /* merge of attr returned only from linkfile creation */                  dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);          }  | 
