diff options
| author | Mohit Agrawal <moagrawa@redhat.com> | 2018-05-31 12:29:35 +0530 | 
|---|---|---|
| committer | Amar Tumballi <amarts@redhat.com> | 2018-07-11 03:13:24 +0000 | 
| commit | e57cbae0bcc3d8649b869eda5ec20f3c6a6d34f0 (patch) | |
| tree | 52059d8e2e38143717b88e6f2683cfacf142463a /xlators/cluster/dht | |
| parent | e31c7a7c0c1ea3f6e931935226fb976a92779ba7 (diff) | |
dht: Inconsistent permission for directories after brick stop/start
Problem: Inconsistent access permissions on directories after
         bringing back the down sub-volumes, in case of directories dht_setattr
         first wind a call on MDS once call is finished on MDS then wind a call
         on NON-MDS.At the time of revalidating dht just compare the uid/gid with
         stbuf uid/gid and if anyone differs set a flag to heal the same.
Solution: Add a condition to compare permission also in dht_revalidate_cbk
          to set a flag to call dht_dir_attr_heal.
BUG: 1584517
Change-Id: I3e039607148005015b5d93364536158380d4c5aa
fixes: bz#1584517
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
Diffstat (limited to 'xlators/cluster/dht')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 81 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 3 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-selfheal.c | 2 | 
3 files changed, 77 insertions, 9 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 07f00b4a92d..900789ca8aa 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1340,6 +1340,8 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          char          gfid_local[GF_UUID_BUF_SIZE] = {0};          char          gfid_node[GF_UUID_BUF_SIZE]  = {0};          int32_t       mds_xattr_val[1]                 = {0}; +        call_frame_t *copy                         = NULL; +        dht_local_t  *copy_local                   = NULL;          GF_VALIDATE_OR_GOTO ("dht", frame, out);          GF_VALIDATE_OR_GOTO ("dht", this, out); @@ -1412,6 +1414,23 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          dht_aggregate_xattr (local->xattr, xattr);                  } +                if (dict_get (xattr, conf->mds_xattr_key)) { +                        local->mds_subvol  = prev; +                        local->mds_stbuf.ia_gid = stbuf->ia_gid; +                        local->mds_stbuf.ia_uid = stbuf->ia_uid; +                        local->mds_stbuf.ia_prot = stbuf->ia_prot; +                } + +                if (local->stbuf.ia_type != IA_INVAL) { +                        if (!__is_root_gfid (stbuf->ia_gfid) && +                            ((local->stbuf.ia_gid != stbuf->ia_gid) || +                            (local->stbuf.ia_uid != stbuf->ia_uid) || +                            (is_permission_different (&local->stbuf.ia_prot, +                                                      &stbuf->ia_prot)))) { +                                local->need_attrheal = 1; +                        } +                } +                  if (local->inode == NULL)                          local->inode = inode_ref (inode); @@ -1507,6 +1526,43 @@ unlock:                                                     &local->postparent, 1);                  } +                if (local->need_attrheal) { +                        local->need_attrheal = 0; +                        if (!__is_root_gfid (inode->gfid)) { +                                gf_uuid_copy (local->gfid, local->mds_stbuf.ia_gfid); +                                local->stbuf.ia_gid = local->mds_stbuf.ia_gid; +                                local->stbuf.ia_uid = local->mds_stbuf.ia_uid; +                                local->stbuf.ia_prot = local->mds_stbuf.ia_prot; +                        } +                        copy = create_frame (this, this->ctx->pool); +                        if (copy) { +                                copy_local = dht_local_init (copy, &local->loc, +                                                             NULL, 0); +                                if (!copy_local) { +                                        DHT_STACK_DESTROY (copy); +                                        goto skip_attr_heal; +                                } +                                copy_local->stbuf = local->stbuf; +                                copy_local->mds_stbuf = local->mds_stbuf; +                                copy_local->mds_subvol = local->mds_subvol; +                                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); +                                if (ret) { +                                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, +                                                DHT_MSG_DIR_ATTR_HEAL_FAILED, +                                                "Synctask creation failed to heal attr " +                                                "for path %s gfid %s ", +                                                local->loc.path, local->gfid); +                                        DHT_STACK_DESTROY (copy); +                                } +                        } +                } + +skip_attr_heal:                  DHT_STRIP_PHASE1_FLAGS (&local->stbuf);                  dht_set_fixed_dir_stat (&local->postparent);                  /* Delete mds xattr at the time of STACK UNWIND */ @@ -1527,7 +1583,7 @@ out:          return ret;  } -int static +int  is_permission_different (ia_prot_t *prot1, ia_prot_t *prot2)  {          if ((prot1->owner.read != prot2->owner.read) || @@ -1688,12 +1744,12 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          {                                  if ((local->stbuf.ia_gid != stbuf->ia_gid) ||                                      (local->stbuf.ia_uid != stbuf->ia_uid) || -                                    (__is_root_gfid (stbuf->ia_gfid) &&                                       is_permission_different (&local->stbuf.ia_prot, -                                                              &stbuf->ia_prot))) { +                                                              &stbuf->ia_prot)) {                                          local->need_selfheal = 1;                                  }                          } +                          if (!dict_get (xattr, conf->mds_xattr_key)) {                                  gf_msg_debug (this->name, 0,                                                "internal xattr %s is not present" @@ -1839,10 +1895,9 @@ out:                          local->need_selfheal = 0;                          if (!__is_root_gfid (inode->gfid)) {                                  gf_uuid_copy (local->gfid, local->mds_stbuf.ia_gfid); -                                if (local->mds_stbuf.ia_gid || local->mds_stbuf.ia_uid) { -                                        local->stbuf.ia_gid = local->mds_stbuf.ia_gid; -                                        local->stbuf.ia_uid = local->mds_stbuf.ia_uid; -                                } +                                local->stbuf.ia_gid = local->mds_stbuf.ia_gid; +                                local->stbuf.ia_uid = local->mds_stbuf.ia_uid; +                                local->stbuf.ia_prot = local->mds_stbuf.ia_prot;                          } else {                                  gf_uuid_copy (local->gfid, local->stbuf.ia_gfid);                                  local->stbuf.ia_gid = local->prebuf.ia_gid; @@ -1854,8 +1909,10 @@ out:                          if (copy) {                                  copy_local = dht_local_init (copy, &local->loc,                                                               NULL, 0); -                                if (!copy_local) +                                if (!copy_local) { +                                        DHT_STACK_DESTROY (copy);                                          goto cont; +                                }                                  copy_local->stbuf = local->stbuf;                                  copy_local->mds_stbuf = local->mds_stbuf;                                  copy_local->mds_subvol = local->mds_subvol; @@ -1865,6 +1922,14 @@ out:                                                      dht_dir_attr_heal,                                                      dht_dir_attr_heal_done,                                                      copy, copy); +                                if (ret) { +                                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, +                                                DHT_MSG_DIR_ATTR_HEAL_FAILED, +                                                "Synctask creation failed to heal attr " +                                                "for path %s gfid %s ", +                                                local->loc.path, local->gfid); +                                        DHT_STACK_DESTROY (copy); +                                }                          }                  }  cont: diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 43bceb9fd2d..02560ef94ab 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -298,6 +298,7 @@ struct dht_local {          xlator_t                *mds_subvol; /* This is use for dir only */          char                     need_selfheal;          char                     need_xattr_heal; +        char                     need_attrheal;          int                      file_count;          int                      dir_count;          call_frame_t            *main_frame; @@ -1488,4 +1489,6 @@ int dht_request_iatt_in_xdata (xlator_t *this, dict_t *xattr_req);  int dht_read_iatt_from_xdata (xlator_t *this, dict_t *xdata,                                struct iatt *stbuf); +int +is_permission_different (ia_prot_t *prot1, ia_prot_t *prot2);  #endif/* _DHT_H */ diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index 6425bdc506e..2aa75bcc4cd 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -2500,7 +2500,7 @@ dht_dir_attr_heal (void *data)                                                NULL, NULL, NULL, NULL);                  } else {                          ret = syncop_setattr (subvol, &local->loc, &local->mds_stbuf, -                                              (GF_SET_ATTR_UID | GF_SET_ATTR_GID), +                                              (GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE),                                                NULL, NULL, NULL, NULL);                  }  | 
