diff options
| -rw-r--r-- | libglusterfs/src/common-utils.c | 15 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 3 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 2 | ||||
| -rw-r--r-- | tests/basic/afr/granular-esh/granular-esh.t | 10 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 8 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.c | 55 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.h | 3 | ||||
| -rw-r--r-- | xlators/features/index/src/index.c | 184 | 
8 files changed, 240 insertions, 40 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 7b19208343f..b9062c159c7 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -4467,6 +4467,21 @@ fop_enum_to_string (glusterfs_fop_t fop)          return "UNKNOWNFOP";  } +const char * +gf_inode_type_to_str (ia_type_t type) +{ +        static const char *const str_ia_type[] = { +                "UNKNOWN", +                "REGULAR FILE", +                "DIRECTORY", +                "LINK", +                "BLOCK DEVICE", +                "CHARACTER DEVICE", +                "PIPE", +                "SOCKET"}; +        return str_ia_type[type]; +} +  gf_boolean_t  gf_is_zero_filled_stat (struct iatt *buf)  { diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index a83678fe322..8d88935ca09 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -37,6 +37,7 @@ void trap (void);  #include "locking.h"  #include "mem-pool.h"  #include "compat-uuid.h" +#include "iatt.h"  #include "uuid.h"  #include "libglusterfs-messages.h" @@ -838,4 +839,6 @@ gf_zero_fill_stat (struct iatt *buf);  gf_boolean_t  is_virtual_xattr (const char *k); +const char * +gf_inode_type_to_str (ia_type_t type);  #endif /* _COMMON_UTILS_H */ diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 1accb62d9e9..3f7bb5ea2e4 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -178,6 +178,8 @@  #define GF_XATTROP_DIRTY_COUNT "glusterfs.xattrop_dirty_count"  #define GF_XATTROP_ENTRY_IN_KEY "glusterfs.xattrop-entry-create"  #define GF_XATTROP_ENTRY_OUT_KEY "glusterfs.xattrop-entry-delete" +#define GF_INDEX_IA_TYPE_GET_REQ "glusterfs.index-ia-type-get-req" +#define GF_INDEX_IA_TYPE_GET_RSP "glusterfs.index-ia-type-get-rsp"  #define GF_HEAL_INFO "glusterfs.heal-info"  #define GF_AFR_HEAL_SBRAIN "glusterfs.heal-sbrain" diff --git a/tests/basic/afr/granular-esh/granular-esh.t b/tests/basic/afr/granular-esh/granular-esh.t index 4adcfc7456a..ee53878e004 100644 --- a/tests/basic/afr/granular-esh/granular-esh.t +++ b/tests/basic/afr/granular-esh/granular-esh.t @@ -149,10 +149,9 @@ TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$ROOT_GFID/dir  TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$ROOT_GFID/newdir  TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$ROOT_GFID/file_stale -# To be uncommented once index xl is made to purge the parent gfid dir on rm -rf -#TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir/f1 -#TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir/f2 -#TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir/f3 +TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir/f1 +TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir/f2 +TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir/f3  TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_newdir/f1  TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_newdir/f2 @@ -164,7 +163,6 @@ TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_newsubdir/f3  TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$ROOT_GFID  TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_newdir  TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_newsubdir -# To be uncommented once index xl is made to purge the parent gfid dir on rm -rf -#TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir +TEST ! stat $B0/${V0}1/.glusterfs/indices/entry-changes/$gfid_dir  cleanup diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index c9a27bf8e20..985cebe76b9 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -567,7 +567,7 @@ afr_selfheal_entry_dirent (call_frame_t *frame, xlator_t *this,                  if ((ret == 0) && (priv->esh_granular) && parent_idx_inode) {                          ret = afr_shd_index_purge (subvol, parent_idx_inode, -                                                   name); +                                                   name, inode->ia_type);                          /* Why is ret force-set to 0? We do not care about                           * index purge failing for full heal as it is quite                           * possible during replace-brick that not all files @@ -748,7 +748,11 @@ afr_selfheal_entry_granular_dirent (xlator_t *subvol, gf_dirent_t *entry,          ret = syncop_lookup (args->xl, &loc, &iatt, NULL, NULL, NULL);          if ((ret == -ENOENT) || (ret == -ESTALE)) { -                afr_shd_index_purge (subvol, parent->inode, entry->d_name); +                /* The name indices under the pgfid index dir are guaranteed +                 * to be regular files. Hence the hardcoding. +                 */ +                afr_shd_index_purge (subvol, parent->inode, entry->d_name, +                                     IA_IFREG);                  ret = 0;                  goto out;          } diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c index b29a822568d..7ccac919769 100644 --- a/xlators/cluster/afr/src/afr-self-heald.c +++ b/xlators/cluster/afr/src/afr-self-heald.c @@ -153,10 +153,13 @@ unlock:  inode_t *  afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid)  { -	inode_t *inode = NULL; -	int ret = 0; -	loc_t loc = {0, }; -	struct iatt iatt = {0, }; +	int           ret      = 0; +        uint64_t       val     = IA_INVAL; +	loc_t         loc      = {0, }; +        dict_t       *xdata    = NULL; +        dict_t       *rsp_dict = NULL; +	inode_t      *inode    = NULL; +	struct iatt   iatt     = {0, };  	inode = inode_find (this->itable, gfid);  	if (inode) @@ -167,12 +170,32 @@ afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid)  		goto out;  	gf_uuid_copy (loc.gfid, gfid); -	ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL); +        xdata = dict_new (); +        if (!xdata) +                goto out; + +        ret = dict_set_int8 (xdata, GF_INDEX_IA_TYPE_GET_REQ, 1); +        if (ret) +                goto out; + +	ret = syncop_lookup (subvol, &loc, &iatt, NULL, xdata, &rsp_dict);  	if (ret < 0)  		goto out; +        if (rsp_dict) { +                ret = dict_get_uint64 (rsp_dict, GF_INDEX_IA_TYPE_GET_RSP, +                                       &val); +                if (ret) +                        goto out; +        } +  	inode = inode_link (loc.inode, NULL, NULL, &iatt); +        ret = inode_ctx_set2 (inode, subvol, 0, &val);  out: +        if (xdata) +                dict_unref (xdata); +        if (rsp_dict) +                dict_unref (rsp_dict);  	loc_wipe (&loc);  	return inode;  } @@ -215,15 +238,19 @@ out:  }  int -afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name) +afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name, +                     ia_type_t type)  { -	loc_t loc = {0, }; -	int ret = 0; +	int    ret = 0; +	loc_t  loc = {0,};  	loc.parent = inode_ref (inode);  	loc.name = name; -	ret = syncop_unlink (subvol, &loc, NULL, NULL); +        if (IA_ISDIR (type)) +                ret = syncop_rmdir (subvol, &loc, 1, NULL, NULL); +        else +                ret = syncop_unlink (subvol, &loc, NULL, NULL);  	loc_wipe (&loc);  	return ret; @@ -395,6 +422,7 @@ afr_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,          afr_private_t        *priv   = NULL;          uuid_t               gfid    = {0};          int                  ret     = 0; +        uint64_t             val     = IA_INVAL;          priv = healer->this->private;          if (!priv->shd.enabled) @@ -407,10 +435,13 @@ afr_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,          if (ret)                  return 0; +        inode_ctx_get2 (parent->inode, subvol, NULL, &val); +          ret = afr_shd_selfheal (healer, healer->subvol, gfid);          if (ret == -ENOENT || ret == -ESTALE) -                afr_shd_index_purge (subvol, parent->inode, entry->d_name); +                afr_shd_index_purge (subvol, parent->inode, entry->d_name, val); +          if (ret == 2)                  /* If bricks crashed in pre-op after creating indices/xattrop                   * link but before setting afr changelogs, we end up with stale @@ -489,6 +520,10 @@ afr_shd_index_sweep_all (struct subvol_healer *healer)                  goto out;          count += ret; +        ret = afr_shd_index_sweep (healer, GF_XATTROP_ENTRY_CHANGES_GFID); +        if (ret < 0) +                goto out; +        count += ret;  out:          if (ret < 0)                  return ret; diff --git a/xlators/cluster/afr/src/afr-self-heald.h b/xlators/cluster/afr/src/afr-self-heald.h index f591515669c..c6ac5ebfd1b 100644 --- a/xlators/cluster/afr/src/afr-self-heald.h +++ b/xlators/cluster/afr/src/afr-self-heald.h @@ -75,5 +75,6 @@ afr_shd_gfid_to_path (xlator_t *this, xlator_t *subvol, uuid_t gfid,                        char **path_p);  int -afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name); +afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name, +                     ia_type_t type);  #endif /* !_AFR_SELF_HEALD_H */ diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index cd40f2587b2..4f431648913 100644 --- a/xlators/features/index/src/index.c +++ b/xlators/features/index/src/index.c @@ -13,6 +13,7 @@  #include "syscall.h"  #include "syncop.h"  #include "common-utils.h" +#include <ftw.h>  #define XATTROP_SUBDIR "xattrop"  #define DIRTY_SUBDIR "dirty" @@ -21,6 +22,7 @@  struct index_syncop_args {          inode_t *parent;          gf_dirent_t *entries; +        char *path;  };  static char *index_vgfid_xattrs[XATTROP_TYPE_END] = { @@ -1482,6 +1484,7 @@ index_lookup_wrapper (call_frame_t *frame, xlator_t *this,          int             ret = 0;          int32_t         op_errno = EINVAL;          int32_t         op_ret = -1; +        uint64_t        val = IA_INVAL;          char            path[PATH_MAX] = {0};          struct iatt     stbuf        = {0, };          struct iatt     postparent = {0,}; @@ -1509,6 +1512,15 @@ index_lookup_wrapper (call_frame_t *frame, xlator_t *this,                  make_index_dir_path (priv->index_basepath, subdir,                                       path, sizeof (path));                  is_dir = _gf_true; + +                if ((xattr_req) && +                    (dict_get (xattr_req, GF_INDEX_IA_TYPE_GET_REQ))) { +                        if (0 == strcmp (subdir, +                                    index_get_subdir_from_type(ENTRY_CHANGES))) +                                val = IA_IFDIR; +                        else +                                val = IA_IFREG; +                }          } else {                  if (!inode_is_linked (loc->inode)) {                          inode_unref (iloc.inode); @@ -1524,12 +1536,12 @@ index_lookup_wrapper (call_frame_t *frame, xlator_t *this,          ret = sys_lstat (path, &lstatbuf);          if (ret) {                  gf_log (this->name, GF_LOG_DEBUG, "Stat failed on %s dir " -                        "(%s)", subdir, strerror (errno)); +                        "(%s)", path, strerror (errno));                  op_errno = errno;                  goto done;          } else if (!S_ISDIR (lstatbuf.st_mode) && is_dir) {                  gf_log (this->name, GF_LOG_DEBUG, "Stat failed on %s dir, " -                        "not a directory", subdir); +                        "not a directory", path);                  op_errno = ENOENT;                  goto done;          } @@ -1539,6 +1551,15 @@ index_lookup_wrapper (call_frame_t *frame, xlator_t *this,                  goto done;          } +        if (val != IA_INVAL) { +                ret = dict_set_uint64 (xattr, GF_INDEX_IA_TYPE_GET_RSP, val); +                if (ret) { +                        op_ret = -1; +                        op_errno = -ret; +                        goto done; +                } +        } +          iatt_from_stat (&stbuf, &lstatbuf);          if (is_dir || inode_is_linked (iloc.inode))                  loc_gfid (&iloc, stbuf.ia_gfid); @@ -1654,6 +1675,116 @@ done:  }  int +deletion_handler (const char *fpath, const struct stat *sb, int typeflag, +               struct FTW *ftwbuf) +{ +        int          ret  = -1; +        ia_type_t    type = IA_INVAL; + +        switch (sb->st_mode & S_IFMT) { +        case S_IFREG: +                sys_unlink (fpath); +                break; + +        case S_IFDIR: +                sys_rmdir (fpath); +                break; +        default: +                type = ia_type_from_st_mode (sb->st_mode); +                gf_log (THIS->name, GF_LOG_WARNING, "%s neither a regular file " +                        "nor a directory - type:%s", fpath, +                        gf_inode_type_to_str (type)); +                break; +        } +        return 0; +} + +static int +index_wipe_index_subdir (void *opaque) +{ +        struct index_syncop_args *args  = opaque; + +        nftw (args->path, deletion_handler, 1, FTW_DEPTH | FTW_PHYS); +        return 0; +} + +static void +index_get_parent_iatt (struct iatt *parent, char *path, loc_t *loc, +                       int32_t *op_ret, int32_t *op_errno) +{ +        int         ret      = -1; +        struct stat lstatbuf = {0,}; + +        ret = sys_lstat (path, &lstatbuf); +        if (ret < 0) { +                *op_ret = -1; +                *op_errno = errno; +                return; +        } + +        iatt_from_stat (parent, &lstatbuf); +        gf_uuid_copy (parent->ia_gfid, loc->pargfid); +        parent->ia_ino = -1; + +        return; +} + +int +index_rmdir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag, +                     dict_t *xdata) +{ +        int                        ret                    = 0; +        int32_t                    op_ret                 = 0; +        int32_t                    op_errno               = 0; +        char                      *subdir                 = NULL; +        char                       index_dir[PATH_MAX]    = {0}; +        char                       index_subdir[PATH_MAX] = {0}; +        uuid_t                     gfid                   = {0}; +        struct  iatt               preparent              = {0}; +        struct  iatt               postparent             = {0}; +        index_priv_t              *priv                   = NULL; +        index_xattrop_type_t       type                   = XATTROP_TYPE_UNSET; +        struct index_syncop_args   args                   = {0,}; + +        priv = this->private; + +        type = index_get_type_from_vgfid (priv, loc->pargfid); +        subdir = index_get_subdir_from_vgfid (priv, loc->pargfid); +        make_index_dir_path (priv->index_basepath, subdir, +                             index_dir, sizeof (index_dir)); + +        index_get_parent_iatt (&preparent, index_dir, loc, &op_ret, &op_errno); +        if (op_ret < 0) +                goto done; + +        gf_uuid_parse (loc->name, gfid); +        make_gfid_path (priv->index_basepath, subdir, gfid, index_subdir, +                        sizeof (index_subdir)); + +        if (flag == 0) { +                ret = index_del (this, gfid, subdir, type); +                if (ret < 0) { +                        op_ret = -1; +                        op_errno = -ret; +                        goto done; +                } +        } else { +                args.path = index_subdir; +                ret = synctask_new (this->ctx->env, index_wipe_index_subdir, +                                    NULL, NULL, &args); +        } + +        index_get_parent_iatt (&postparent, index_dir, loc, &op_ret, &op_errno); +        if (op_ret < 0) +                goto done; + +done: +        INDEX_STACK_UNWIND (rmdir, frame, op_ret, op_errno, &preparent, +                            &postparent, xdata); +        return 0; +} + +int  index_unlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,                        dict_t *xdata)  { @@ -1667,7 +1798,6 @@ index_unlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,          struct  iatt    postparent = {0};          char            index_dir[PATH_MAX] = {0};          char            filepath[PATH_MAX] = {0}; -        struct  stat    lstatbuf = {0};          uuid_t          gfid = {0};          char            *subdir = NULL; @@ -1681,16 +1811,9 @@ index_unlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,                  goto done;          } -        ret = sys_lstat (index_dir, &lstatbuf); -        if (ret < 0) { -                op_ret = -1; -                op_errno = errno; +        index_get_parent_iatt (&preparent, index_dir, loc, &op_ret, &op_errno); +        if (op_ret < 0)                  goto done; -        } - -        iatt_from_stat (&preparent, &lstatbuf); -        gf_uuid_copy (preparent.ia_gfid, loc->pargfid); -        preparent.ia_ino = -1;          if (type <= XATTROP_TYPE_UNSET) {                  ret = index_inode_ctx_get (loc->parent, this, &ictx); @@ -1716,16 +1839,9 @@ index_unlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,                  goto done;          } -        memset (&lstatbuf, 0, sizeof (lstatbuf)); -        ret = sys_lstat (index_dir, &lstatbuf); -        if (ret < 0) { -                op_ret = -1; -                op_errno = errno; +        index_get_parent_iatt (&postparent, index_dir, loc, &op_ret, &op_errno); +        if (op_ret < 0)                  goto done; -        } -        iatt_from_stat (&postparent, &lstatbuf); -        gf_uuid_copy (postparent.ia_gfid, loc->pargfid); -        postparent.ia_ino = -1;  done:          INDEX_STACK_UNWIND (unlink, frame, op_ret, op_errno, &preparent,                              &postparent, xdata); @@ -2010,6 +2126,31 @@ out:  }  int +index_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, +             dict_t *xdata) +{ +        call_stub_t     *stub = NULL; +        index_priv_t    *priv = NULL; + +        priv = this->private; +        if (!index_is_fop_on_internal_inode (this, loc->parent, NULL)) +                goto out; + +        stub = fop_rmdir_stub (frame, index_rmdir_wrapper, loc, flags, xdata); +        if (!stub) { +                STACK_UNWIND_STRICT (rmdir, frame, -1, ENOMEM, NULL, NULL, +                                     NULL); +                return 0; +        } +        worker_enqueue (this, stub); +        return 0; +out: +        STACK_WIND_TAIL (frame, FIRST_CHILD(this), +                         FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); +        return 0; +} + +int  index_make_xattrop_watchlist (xlator_t *this, index_priv_t *priv,                                char *watchlist, index_xattrop_type_t type)  { @@ -2333,6 +2474,7 @@ struct xlator_fops fops = {          .opendir     = index_opendir,          .readdir     = index_readdir,          .unlink      = index_unlink, +        .rmdir       = index_rmdir,          .fstat       = index_fstat,  };  | 
