diff options
Diffstat (limited to 'xlators/features/index/src/index.c')
-rw-r--r-- | xlators/features/index/src/index.c | 184 |
1 files changed, 163 insertions, 21 deletions
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, }; |