diff options
| author | shishir gowda <sgowda@redhat.com> | 2012-10-18 15:40:02 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2012-11-29 13:56:11 -0800 | 
| commit | 01cd59506e8021b4adb7fe8b4877a7e60beb13f6 (patch) | |
| tree | e7f19fb30eac2910b060a72c9655a3878334268c /xlators/cluster/dht/src | |
| parent | 9864b3a8e46c2813a5793ce7ac7d3029ed324828 (diff) | |
cluster/dht: Heal dir uid/gid
Identify mismatching uid/gid in lookup, and trigger a syncop
heal. uid/gid of subvol with latest ctime is trusted (local->prebuf).
Change-Id: Ib5c4bc438e7f4b1f33080e73593f40f400e997f0
BUG: 862967
Signed-off-by: shishir gowda <sgowda@redhat.com>
Reviewed-on: http://review.gluster.org/3964
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/cluster/dht/src')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 42 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 7 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-layout.c | 10 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-selfheal.c | 47 | 
4 files changed, 105 insertions, 1 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 98560685bce..0925b6d2471 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -525,6 +525,8 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          int           ret  = -1;          int           is_dir = 0;          int           is_linkfile = 0; +        call_frame_t *copy          = NULL; +        dht_local_t  *copy_local    = NULL;          GF_VALIDATE_OR_GOTO ("dht", frame, err);          GF_VALIDATE_OR_GOTO ("dht", this, err); @@ -595,6 +597,23 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  }                  if (is_dir) { +                        ret = dht_dir_has_layout (xattr); +                        if (ret >= 0) { +                                if (is_greater_time(local->stbuf.ia_ctime, +                                                    local->stbuf.ia_ctime_nsec, +                                                    stbuf->ia_ctime, +                                                    stbuf->ia_ctime_nsec)) { +                                        local->prebuf.ia_gid = stbuf->ia_gid; +                                        local->prebuf.ia_uid = stbuf->ia_uid; +                                } +                        } +                        if (local->stbuf.ia_type != IA_INVAL) +                        { +                                if ((local->stbuf.ia_gid != stbuf->ia_gid) || +                                    (local->stbuf.ia_uid != stbuf->ia_uid)) { +                                        local->need_selfheal = 1; +                                } +                        }                          ret = dht_layout_dir_mismatch (this, layout,                                                         prev->this, &local->loc,                                                         xattr); @@ -633,7 +652,28 @@ out:                      && (conf && conf->unhashed_sticky_bit)) {                          local->stbuf.ia_prot.sticky = 1;                  } -                if (local->layout_mismatch) { +                if (local->need_selfheal) { +                        local->need_selfheal = 0; +                        uuid_copy (local->gfid, local->stbuf.ia_gfid); +                        local->stbuf.ia_gid = local->prebuf.ia_gid; +                        local->stbuf.ia_uid = local->prebuf.ia_uid; +                        copy = create_frame (this, this->ctx->pool); +                        if (copy) { +                                copy_local = dht_local_init (copy, &local->loc, +                                                             NULL, 0); +                                if (!copy_local) +                                        goto cont; +                                copy_local->stbuf = local->stbuf; +                                copy->local = copy_local; +                                FRAME_SU_DO (copy, dht_local_t); +                                ret = synctask_new (this->ctx->env, +                                                    dht_dir_attr_heal, +                                                    dht_dir_attr_heal_done, +                                                    copy, copy); +                        } +                } +cont: +		if (local->layout_mismatch) {                          /* Found layout mismatch in the directory, need to                             fix this in the inode context */                          dht_layout_unref (this, local->layout); diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 0f2df514fb5..1a69feba607 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -370,6 +370,7 @@ typedef enum {                  UNLOCK (&inode->lock);                                  \          } while (0) +#define is_greater_time(a, an, b, bn) (((a) < (b)) || (((a) == (b)) && ((an) < (bn))))  dht_layout_t                            *dht_layout_new (xlator_t *this, int cnt);  dht_layout_t                            *dht_layout_get (xlator_t *this, inode_t *inode);  dht_layout_t                            *dht_layout_for_subvol (xlator_t *this, xlator_t *subvol); @@ -715,4 +716,10 @@ dht_inode_ctx_time_update (inode_t *inode, xlator_t *this, struct iatt *stat,  int dht_inode_ctx_get (inode_t *inode, xlator_t *this, dht_inode_ctx_t **ctx);  int dht_inode_ctx_set (inode_t *inode, xlator_t *this, dht_inode_ctx_t *ctx); +int +dht_dir_attr_heal (void *data); +int +dht_dir_attr_heal_done (int ret, call_frame_t *sync_frame, void *data); +int +dht_dir_has_layout (dict_t *xattr);  #endif/* _DHT_H */ diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c index 19807607758..993f6166a12 100644 --- a/xlators/cluster/dht/src/dht-layout.c +++ b/xlators/cluster/dht/src/dht-layout.c @@ -615,6 +615,16 @@ out:          return ret;  } +int +dht_dir_has_layout (dict_t *xattr) +{ + +        void     *disk_layout_raw = NULL; + +        return dict_get_ptr (xattr, "trusted.glusterfs.dht", +                             &disk_layout_raw); + +}  int  dht_layout_dir_mismatch (xlator_t *this, dht_layout_t *layout, xlator_t *subvol, diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index 8ac5a9e9e44..7a5d4d116ad 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -858,3 +858,50 @@ dht_selfheal_restore (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,          return ret;  } + +int +dht_dir_attr_heal (void *data) +{ +        call_frame_t    *frame = NULL; +        dht_local_t     *local = NULL; +        xlator_t        *subvol = NULL; +        xlator_t        *this  = NULL; +        dht_conf_t      *conf  = NULL; +        int              call_cnt = 0; +        int              ret   = -1; +        int              i     = 0; + +        GF_VALIDATE_OR_GOTO ("dht", data, out); + +        frame = data; +        local = frame->local; +        this = frame->this; +        GF_VALIDATE_OR_GOTO ("dht", this, out); +        GF_VALIDATE_OR_GOTO ("dht", local, out); +        conf = this->private; +        GF_VALIDATE_OR_GOTO ("dht", conf, out); + +        call_cnt = conf->subvolume_cnt; + +        for (i = 0; i < call_cnt; i++) { +                subvol = conf->subvolumes[i]; +                if (!subvol || (subvol == dht_first_up_subvol (this))) +                        continue; +                ret = syncop_setattr (subvol, &local->loc, &local->stbuf, +                                      (GF_SET_ATTR_UID | GF_SET_ATTR_GID), +                                      NULL, NULL); +                if (ret) +                        gf_log ("dht", GF_LOG_ERROR, "Failed to set uid/gid on" +                                " %s on %s subvol (%s)", local->loc.path, +                                subvol->name, strerror (errno)); +        } +out: +        return 0; +} + +int +dht_dir_attr_heal_done (int ret, call_frame_t *sync_frame, void *data) +{ +        DHT_STACK_DESTROY (sync_frame); +        return 0; +}  | 
