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, }; |