diff options
| author | Vijaykumar M <vmallika@redhat.com> | 2013-12-13 14:18:16 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2014-02-02 23:10:38 -0800 | 
| commit | 3023a50c1410b4da457e86bed69c320760d37344 (patch) | |
| tree | 7d8f1a89e1150155f7c840d56f9f160e4ad207e3 /xlators | |
| parent | 922134fdc08afb2810cb0205f26693d36db6fd4e (diff) | |
dht: do not remove linkfile if file exist in cached sub volume
Currently with rmdir, if a directory contains only the linkfiles
we remove all the linkfiles and this is causing the problem when the cached
sub volume is down and end-up with duplicate files showing on the mount point.
Solution: Before removing a linkfile check if the
files exists in cached subvolume.
Change-Id: Iedffd0d9298ec8bb95d5ce27c341c9ade81f0d3c
BUG: 1042725
Signed-off-by: Vijaykumar M <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/6500
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 128 | 
1 files changed, 109 insertions, 19 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index cf4ec258d..959afe873 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -4611,17 +4611,85 @@ err:  int +dht_rmdir_cached_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                             int op_ret, int op_errno, inode_t *inode, +                             struct iatt *stbuf, dict_t *xattr, +                             struct iatt *parent) +{ +        dht_local_t    *local         = NULL; +        xlator_t       *src           = NULL; +        call_frame_t   *main_frame    = NULL; +        dht_local_t    *main_local    = NULL; +        int             this_call_cnt = 0; +        dht_conf_t     *conf          = this->private; +        dict_t         *xattrs        = NULL; +        int             ret           = 0; + +        local = frame->local; +        src   = local->hashed_subvol; + +        main_frame = local->main_frame; +        main_local = main_frame->local; + +        if (op_ret == 0) { +                main_local->op_ret  = -1; +                main_local->op_errno = ENOTEMPTY; + +                gf_log (this->name, GF_LOG_WARNING, +                        "%s found on cached subvol %s", +                        local->loc.path, src->name); +                goto err; +        } else if (op_errno != ENOENT) { +                main_local->op_ret  = -1; +                main_local->op_errno = op_errno; +                goto err; +        } + +        xattrs = dict_new (); +        if (!xattrs) { +                gf_log (this->name, GF_LOG_ERROR, "dict_new failed"); +                goto err; +        } + +        ret = dict_set_uint32 (xattrs, conf->link_xattr_name, 256); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "failed to set linkto key" +                        " in dict"); +                if (xattrs) +                        dict_unref (xattrs); +                goto err; +        } + +        STACK_WIND (frame, dht_rmdir_lookup_cbk, +                    src, src->fops->lookup, &local->loc, xattrs); +        if (xattrs) +                dict_unref (xattrs); + +        return 0; +err: + +        this_call_cnt = dht_frame_return (main_frame); +        if (is_last_call (this_call_cnt)) +                dht_rmdir_do (main_frame, this); + +        DHT_STACK_DESTROY (frame); +        return 0; +} + + +int  dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,                             gf_dirent_t *entries, xlator_t *src)  { -        int                 ret = 0; -        int                 build_ret = 0; -        gf_dirent_t        *trav = NULL; +        int                 ret          = 0; +        int                 build_ret    = 0; +        gf_dirent_t        *trav         = NULL;          call_frame_t       *lookup_frame = NULL;          dht_local_t        *lookup_local = NULL; -        dht_local_t        *local = NULL; -        dict_t             *xattrs = NULL; -        dht_conf_t         *conf = this->private; +        dht_local_t        *local        = NULL; +        dict_t             *xattrs       = NULL; +        dht_conf_t         *conf         = this->private; +        xlator_t           *subvol       = NULL;          local = frame->local; @@ -4681,6 +4749,7 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,                  lookup_frame->local = lookup_local;                  lookup_local->main_frame = frame; +                lookup_local->hashed_subvol = src;                  build_ret = dht_build_child_loc (this, &lookup_local->loc,                                                   &local->loc, trav->d_name); @@ -4699,9 +4768,20 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,                  }                  UNLOCK (&frame->lock); -                STACK_WIND (lookup_frame, dht_rmdir_lookup_cbk, -                            src, src->fops->lookup, -                            &lookup_local->loc, xattrs); +                subvol = dht_linkfile_subvol (this, NULL, &trav->d_stat, +                                              trav->dict); +                if (!subvol) { +                        gf_log (this->name, GF_LOG_INFO, +                                "linkfile not having link subvolume. path=%s", +                                lookup_local->loc.path); +                        STACK_WIND (lookup_frame, dht_rmdir_lookup_cbk, +                                    src, src->fops->lookup, +                                    &lookup_local->loc, xattrs); +                } else { +                        STACK_WIND (lookup_frame, dht_rmdir_cached_lookup_cbk, +                                    subvol, subvol->fops->lookup, +                                    &lookup_local->loc, xattrs); +                }                  ret++;          } @@ -4767,16 +4847,18 @@ int  dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                         int op_ret, int op_errno, fd_t *fd, dict_t *xdata)  { -        dht_local_t  *local = NULL; +        dht_local_t  *local         = NULL;          int           this_call_cnt = -1; -        call_frame_t *prev = NULL; -        dict_t       *dict = NULL; -        int           ret = 0; -        dht_conf_t   *conf = this->private; +        call_frame_t *prev          = NULL; +        dict_t       *dict          = NULL; +        int           ret           = 0; +        dht_conf_t   *conf          = this->private; +        int           i             = 0;          local = frame->local;          prev  = cookie; +        this_call_cnt = dht_frame_return (frame);          if (op_ret == -1) {                  gf_log (this->name, GF_LOG_DEBUG,                          "opendir on %s for %s failed (%s)", @@ -4789,6 +4871,12 @@ dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto err;          } +        if (!is_last_call (this_call_cnt)) +                return 0; + +        if (local->op_ret == -1) +                goto err; +          dict = dict_new ();          if (!dict) {                  local->op_ret = -1; @@ -4802,9 +4890,13 @@ dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          "%s: failed to set '%s' key",                          local->loc.path, conf->link_xattr_name); -        STACK_WIND (frame, dht_rmdir_readdirp_cbk, -                    prev->this, prev->this->fops->readdirp, -                    local->fd, 4096, 0, dict); +        local->call_cnt = conf->subvolume_cnt; +        for (i = 0; i < conf->subvolume_cnt; i++) { +                STACK_WIND (frame, dht_rmdir_readdirp_cbk, +                            conf->subvolumes[i], +                            conf->subvolumes[i]->fops->readdirp, +                            local->fd, 4096, 0, dict); +        }          if (dict)                  dict_unref (dict); @@ -4812,8 +4904,6 @@ dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          return 0;  err: -        this_call_cnt = dht_frame_return (frame); -          if (is_last_call (this_call_cnt)) {                  dht_rmdir_do (frame, this);          }  | 
