diff options
| author | Amar Tumballi <amarts@redhat.com> | 2018-12-06 12:29:25 +0530 | 
|---|---|---|
| committer | Amar Tumballi <amarts@redhat.com> | 2018-12-13 17:10:00 +0000 | 
| commit | 8293d21280fd6ddfc9bb54068cf87794fc6be207 (patch) | |
| tree | 39729fb407b436ed0cc3e4a9f4e5bbd29036a9db | |
| parent | af7e957b4954bd84b8f7df6bfbd59c939092ead2 (diff) | |
all: remove code which is not being considered in build
These xlators are now removed from build as per discussion/announcement
done at https://lists.gluster.org/pipermail/gluster-users/2018-July/034400.html
* move rot-13 to playground, as it is used only as demo
  purpose, and is documented in many places.
* Removed code of below xlators:
  - cluster/stripe
  - cluster/tier
  - features/changetimerecorder
  - features/glupy
  - performance/symlink-cache
  - encryption/crypt
  - storage/bd
  - experimental/posix2
  - experimental/dht2
  - experimental/fdl
  - experimental/jbr
updates: bz#1635688
Change-Id: I1d2d63c32535e149bc8dcb2daa76236c707996e8
Signed-off-by: Amar Tumballi <amarts@redhat.com>
113 files changed, 0 insertions, 37439 deletions
diff --git a/xlators/cluster/dht/src/tier-common.c b/xlators/cluster/dht/src/tier-common.c deleted file mode 100644 index b22f4776ada..00000000000 --- a/xlators/cluster/dht/src/tier-common.c +++ /dev/null @@ -1,1199 +0,0 @@ -/* -  Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include "libxlator.h" -#include "dht-common.h" -#include <glusterfs/defaults.h> -#include "tier-common.h" -#include "tier.h" - -int -dht_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -             int op_errno, inode_t *inode, struct iatt *stbuf, -             struct iatt *preparent, struct iatt *postparent, dict_t *xdata); - -int -tier_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -              int op_errno, inode_t *inode, struct iatt *stbuf, -              struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    dht_local_t *local = NULL; -    loc_t *oldloc = NULL; -    loc_t *newloc = NULL; - -    local = frame->local; - -    oldloc = &local->loc; -    newloc = &local->loc2; - -    if (op_ret == -1) { -        /* No continuation on DHT inode missing errors, as we should -         * then have a good stbuf that states P2 happened. We would -         * get inode missing if, the file completed migrated between -         * the lookup and the link call */ -        goto out; -    } - -    if (local->call_cnt != 1) { -        goto out; -    } - -    local->call_cnt = 2; - -    /* Do this on the hot tier now */ - -    STACK_WIND(frame, tier_link_cbk, local->cached_subvol, -               local->cached_subvol->fops->link, oldloc, newloc, xdata); - -    return 0; - -out: -    DHT_STRIP_PHASE1_FLAGS(stbuf); - -    DHT_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, -                     postparent, NULL); - -    return 0; -} - -int -tier_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -          dict_t *xdata) -{ -    xlator_t *cached_subvol = NULL; -    xlator_t *hashed_subvol = NULL; -    int op_errno = -1; -    int ret = -1; -    dht_local_t *local = NULL; -    dht_conf_t *conf = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(oldloc, err); -    VALIDATE_OR_GOTO(newloc, err); - -    conf = this->private; - -    local = dht_local_init(frame, oldloc, NULL, GF_FOP_LINK); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->call_cnt = 1; - -    cached_subvol = local->cached_subvol; - -    if (!cached_subvol) { -        gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", -                     oldloc->path); -        op_errno = ENOENT; -        goto err; -    } - -    hashed_subvol = TIER_HASHED_SUBVOL; - -    ret = loc_copy(&local->loc2, newloc); -    if (ret == -1) { -        op_errno = ENOMEM; -        goto err; -    } - -    if (hashed_subvol == cached_subvol) { -        STACK_WIND(frame, dht_link_cbk, cached_subvol, -                   cached_subvol->fops->link, oldloc, newloc, xdata); -        return 0; -    } - -    /* Create hardlinks to both the data file on the hot tier -       and the linkto file on the cold tier */ - -    gf_uuid_copy(local->gfid, oldloc->inode->gfid); - -    STACK_WIND(frame, tier_link_cbk, hashed_subvol, hashed_subvol->fops->link, -               oldloc, newloc, xdata); - -    return 0; -err: -    op_errno = (op_errno == -1) ? errno : op_errno; -    DHT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -    return 0; -} - -int -tier_create_unlink_stale_linkto_cbk(call_frame_t *frame, void *cookie, -                                    xlator_t *this, int op_ret, int op_errno, -                                    struct iatt *preparent, -                                    struct iatt *postparent, dict_t *xdata) -{ -    dht_local_t *local = NULL; - -    local = frame->local; - -    if (local->params) { -        dict_del(local->params, GLUSTERFS_INTERNAL_FOP_KEY); -    } - -    DHT_STACK_UNWIND(create, frame, -1, local->op_errno, NULL, NULL, NULL, NULL, -                     NULL, NULL); - -    return 0; -} - -int -tier_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, -                struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    xlator_t *prev = NULL; -    int ret = -1; -    dht_local_t *local = NULL; -    xlator_t *hashed_subvol = NULL; -    dht_conf_t *conf = NULL; - -    local = frame->local; -    conf = this->private; - -    hashed_subvol = TIER_HASHED_SUBVOL; - -    if (!local) { -        op_ret = -1; -        op_errno = EINVAL; -        goto out; -    } - -    if (op_ret == -1) { -        if (local->linked == _gf_true && local->xattr_req) { -            local->op_errno = op_errno; -            local->op_ret = op_ret; -            ret = dht_fill_dict_to_avoid_unlink_of_migrating_file( -                local->xattr_req); -            if (ret) { -                gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, -                       "Failed to set dictionary value to " -                       "unlink of migrating file"); -                goto out; -            } - -            STACK_WIND(frame, tier_create_unlink_stale_linkto_cbk, -                       hashed_subvol, hashed_subvol->fops->unlink, &local->loc, -                       0, local->xattr_req); -            return 0; -        } -        goto out; -    } - -    prev = cookie; - -    if (local->loc.parent) { -        dht_inode_ctx_time_update(local->loc.parent, this, preparent, 0); - -        dht_inode_ctx_time_update(local->loc.parent, this, postparent, 1); -    } - -    ret = dht_layout_preset(this, prev, inode); -    if (ret != 0) { -        gf_msg_debug(this->name, 0, "could not set preset layout for subvol %s", -                     prev->name); -        op_ret = -1; -        op_errno = EINVAL; -        goto out; -    } - -    local->op_errno = op_errno; - -    if (local->linked == _gf_true) { -        local->stbuf = *stbuf; -        dht_linkfile_attr_heal(frame, this); -    } -out: -    if (local) { -        if (local->xattr_req) { -            dict_del(local->xattr_req, TIER_LINKFILE_GFID); -        } -    } - -    DHT_STRIP_PHASE1_FLAGS(stbuf); - -    DHT_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, -                     preparent, postparent, xdata); - -    return 0; -} - -int -tier_create_linkfile_create_cbk(call_frame_t *frame, void *cookie, -                                xlator_t *this, int32_t op_ret, -                                int32_t op_errno, inode_t *inode, -                                struct iatt *stbuf, struct iatt *preparent, -                                struct iatt *postparent, dict_t *xdata) -{ -    dht_local_t *local = NULL; -    xlator_t *cached_subvol = NULL; -    dht_conf_t *conf = NULL; -    int ret = -1; -    unsigned char *gfid = NULL; - -    local = frame->local; -    if (!local) { -        op_errno = EINVAL; -        goto err; -    } - -    if (op_ret == -1) { -        local->op_errno = op_errno; -        goto err; -    } - -    conf = this->private; -    if (!conf) { -        local->op_errno = EINVAL; -        op_errno = EINVAL; -        goto err; -    } - -    cached_subvol = TIER_UNHASHED_SUBVOL; - -    if (local->params) { -        dict_del(local->params, conf->link_xattr_name); -        dict_del(local->params, GLUSTERFS_INTERNAL_FOP_KEY); -    } - -    /* -     * We will delete the linkfile if data file creation fails. -     * When deleting this stale linkfile, there is a possibility -     * for a race between this linkfile deletion and a stale -     * linkfile deletion triggered by another lookup from different -     * client. -     * -     * For eg: -     * -     *     Client 1                        Client 2 -     * -     * 1   linkfile created for foo -     * -     * 2   data file creation failed -     * -     * 3                                   creating a file with same name -     * -     * 4                                   lookup before creation deleted -     *                                     the linkfile created by client1 -     *                                     considering as a stale linkfile. -     * -     * 5                                   New linkfile created for foo -     *                                     with different gfid. -     * -     * 6 Trigger linkfile deletion as -     *   data file creation failed. -     * -     * 7 Linkfile deleted which is -     *   created by client2. -     * -     * 8                                   Data file created. -     * -     * With this race, we will end up having a file in a non-hashed subvol -     * without a linkfile in hashed subvol. -     * -     * To avoid this, we store the gfid of linkfile created by client, So -     * If we delete the linkfile , we validate gfid of existing file with -     * stored value from posix layer. -     * -     * Storing this value in local->xattr_req as local->params was also used -     * to create the data file. During the linkfile deletion we will use -     * local->xattr_req dictionary. -     */ -    if (!local->xattr_req) { -        local->xattr_req = dict_new(); -        if (!local->xattr_req) { -            local->op_errno = ENOMEM; -            op_errno = ENOMEM; -            goto err; -        } -    } - -    gfid = GF_MALLOC(sizeof(uuid_t), gf_common_mt_char); -    if (!gfid) { -        local->op_errno = ENOMEM; -        op_errno = ENOMEM; -        goto err; -    } - -    gf_uuid_copy(gfid, stbuf->ia_gfid); -    ret = dict_set_dynptr(local->xattr_req, TIER_LINKFILE_GFID, gfid, -                          sizeof(uuid_t)); -    if (ret) { -        GF_FREE(gfid); -        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, -               "Failed to set dictionary value" -               " : key = %s", -               TIER_LINKFILE_GFID); -    } - -    STACK_WIND_COOKIE(frame, tier_create_cbk, cached_subvol, cached_subvol, -                      cached_subvol->fops->create, &local->loc, local->flags, -                      local->mode, local->umask, local->fd, local->params); - -    return 0; -err: -    DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, -                     NULL); -    return 0; -} - -gf_boolean_t -tier_is_hot_tier_decommissioned(xlator_t *this) -{ -    dht_conf_t *conf = NULL; -    xlator_t *hot_tier = NULL; -    int i = 0; - -    conf = this->private; -    hot_tier = conf->subvolumes[1]; - -    if (conf->decommission_subvols_cnt) { -        for (i = 0; i < conf->subvolume_cnt; i++) { -            if (conf->decommissioned_bricks[i] && -                conf->decommissioned_bricks[i] == hot_tier) -                return _gf_true; -        } -    } - -    return _gf_false; -} - -int -tier_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -            mode_t mode, mode_t umask, fd_t *fd, dict_t *params) -{ -    int op_errno = -1; -    dht_local_t *local = NULL; -    dht_conf_t *conf = NULL; -    xlator_t *hot_subvol = NULL; -    xlator_t *cold_subvol = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); - -    conf = this->private; - -    dht_get_du_info(frame, this, loc); - -    local = dht_local_init(frame, loc, fd, GF_FOP_CREATE); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    cold_subvol = TIER_HASHED_SUBVOL; -    hot_subvol = TIER_UNHASHED_SUBVOL; - -    if (conf->subvolumes[0] != cold_subvol) { -        hot_subvol = conf->subvolumes[0]; -    } -    /* -     * if hot tier full, write to cold. -     * Also if hot tier is full, create in cold -     */ -    if (dht_is_subvol_filled(this, hot_subvol) || -        tier_is_hot_tier_decommissioned(this)) { -        gf_msg_debug(this->name, 0, "creating %s on %s", loc->path, -                     cold_subvol->name); - -        STACK_WIND_COOKIE(frame, tier_create_cbk, cold_subvol, cold_subvol, -                          cold_subvol->fops->create, loc, flags, mode, umask, -                          fd, params); -    } else { -        local->params = dict_ref(params); -        local->flags = flags; -        local->mode = mode; -        local->umask = umask; -        local->cached_subvol = hot_subvol; -        local->hashed_subvol = cold_subvol; - -        gf_msg_debug(this->name, 0, "creating %s on %s (link at %s)", loc->path, -                     hot_subvol->name, cold_subvol->name); - -        dht_linkfile_create(frame, tier_create_linkfile_create_cbk, this, -                            hot_subvol, cold_subvol, loc); - -        goto out; -    } -out: -    return 0; - -err: - -    op_errno = (op_errno == -1) ? errno : op_errno; -    DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, -                     NULL); - -    return 0; -} - -int -tier_unlink_nonhashed_linkfile_cbk(call_frame_t *frame, void *cookie, -                                   xlator_t *this, int op_ret, int op_errno, -                                   struct iatt *preparent, -                                   struct iatt *postparent, dict_t *xdata) -{ -    dht_local_t *local = NULL; -    xlator_t *prev = NULL; - -    local = frame->local; -    prev = cookie; - -    LOCK(&frame->lock); -    { -        if ((op_ret == -1) && (op_errno != ENOENT)) { -            local->op_errno = op_errno; -            local->op_ret = op_ret; -            gf_msg_debug(this->name, op_errno, -                         "Unlink link: subvolume %s" -                         " returned -1", -                         prev->name); -            goto unlock; -        } - -        local->op_ret = 0; -    } -unlock: -    UNLOCK(&frame->lock); - -    if (local->op_ret == -1) -        goto err; -    DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, -                     &local->preparent, &local->postparent, NULL); - -    return 0; - -err: -    DHT_STACK_UNWIND(unlink, frame, -1, local->op_errno, NULL, NULL, NULL); -    return 0; -} - -int -tier_unlink_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int op_ret, int op_errno, inode_t *inode, -                       struct iatt *preparent, dict_t *xdata, -                       struct iatt *postparent) -{ -    dht_local_t *local = NULL; -    xlator_t *prev = NULL; -    dht_conf_t *conf = NULL; -    xlator_t *hot_subvol = NULL; - -    local = frame->local; -    prev = cookie; -    conf = this->private; -    hot_subvol = TIER_UNHASHED_SUBVOL; - -    if (!op_ret) { -        /* -         * linkfile present on hot tier. unlinking the linkfile -         */ -        STACK_WIND_COOKIE(frame, tier_unlink_nonhashed_linkfile_cbk, hot_subvol, -                          hot_subvol, hot_subvol->fops->unlink, &local->loc, -                          local->flags, NULL); -        return 0; -    } - -    LOCK(&frame->lock); -    { -        if (op_errno == ENOENT) { -            local->op_ret = 0; -            local->op_errno = op_errno; -        } else { -            local->op_ret = op_ret; -            local->op_errno = op_errno; -        } -        gf_msg_debug(this->name, op_errno, "Lookup : subvolume %s returned -1", -                     prev->name); -    } - -    UNLOCK(&frame->lock); - -    DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, -                     &local->preparent, &local->postparent, xdata); - -    return 0; -} - -int -tier_unlink_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                         int op_ret, int op_errno, struct iatt *preparent, -                         struct iatt *postparent, dict_t *xdata) -{ -    dht_local_t *local = NULL; -    xlator_t *prev = NULL; - -    local = frame->local; -    prev = cookie; - -    LOCK(&frame->lock); -    { -        /* Ignore EINVAL for tier to ignore error when the file -                does not exist on the other tier  */ -        if ((op_ret == -1) && !((op_errno == ENOENT) || (op_errno == EINVAL))) { -            local->op_errno = op_errno; -            local->op_ret = op_ret; -            gf_msg_debug(this->name, op_errno, -                         "Unlink link: subvolume %s" -                         " returned -1", -                         prev->name); -            goto unlock; -        } - -        local->op_ret = 0; -    } -unlock: -    UNLOCK(&frame->lock); - -    if (local->op_ret == -1) -        goto err; - -    DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, -                     &local->preparent, &local->postparent, xdata); - -    return 0; - -err: -    DHT_STACK_UNWIND(unlink, frame, -1, local->op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -tier_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                int op_errno, struct iatt *preparent, struct iatt *postparent, -                dict_t *xdata) -{ -    dht_local_t *local = NULL; -    xlator_t *prev = NULL; -    struct iatt *stbuf = NULL; -    dht_conf_t *conf = NULL; -    int ret = -1; -    xlator_t *hot_tier = NULL; -    xlator_t *cold_tier = NULL; - -    local = frame->local; -    prev = cookie; -    conf = this->private; - -    cold_tier = TIER_HASHED_SUBVOL; -    hot_tier = TIER_UNHASHED_SUBVOL; - -    LOCK(&frame->lock); -    { -        if (op_ret == -1) { -            if (op_errno == ENOENT) { -                local->op_ret = 0; -            } else { -                local->op_ret = -1; -                local->op_errno = op_errno; -            } -            gf_msg_debug(this->name, op_errno, -                         "Unlink: subvolume %s returned -1" -                         " with errno = %d", -                         prev->name, op_errno); -            goto unlock; -        } - -        local->op_ret = 0; - -        local->postparent = *postparent; -        local->preparent = *preparent; - -        if (local->loc.parent) { -            dht_inode_ctx_time_update(local->loc.parent, this, -                                      &local->preparent, 0); -            dht_inode_ctx_time_update(local->loc.parent, this, -                                      &local->postparent, 1); -        } -    } -unlock: -    UNLOCK(&frame->lock); - -    if (local->op_ret) -        goto out; - -    if (cold_tier != local->cached_subvol) { -        /* -         * File is present in hot tier, so there will be -         * a link file on cold tier, deleting the linkfile -         * from cold tier -         */ -        STACK_WIND_COOKIE(frame, tier_unlink_linkfile_cbk, cold_tier, cold_tier, -                          cold_tier->fops->unlink, &local->loc, local->flags, -                          xdata); -        return 0; -    } - -    ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); -    if (!ret && stbuf && -        ((IS_DHT_MIGRATION_PHASE2(stbuf)) || IS_DHT_MIGRATION_PHASE1(stbuf))) { -        /* -         * File is migrating from cold to hot tier. -         * Delete the destination linkfile. -         */ -        STACK_WIND_COOKIE(frame, tier_unlink_lookup_cbk, hot_tier, hot_tier, -                          hot_tier->fops->lookup, &local->loc, NULL); -        return 0; -    } - -out: -    DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, -                     &local->preparent, &local->postparent, xdata); - -    return 0; -} - -int -tier_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, -            dict_t *xdata) -{ -    xlator_t *cached_subvol = NULL; -    xlator_t *hashed_subvol = NULL; -    dht_conf_t *conf = NULL; -    int op_errno = -1; -    dht_local_t *local = NULL; -    int ret = -1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); - -    conf = this->private; - -    local = dht_local_init(frame, loc, NULL, GF_FOP_UNLINK); -    if (!local) { -        op_errno = ENOMEM; - -        goto err; -    } - -    hashed_subvol = TIER_HASHED_SUBVOL; - -    cached_subvol = local->cached_subvol; -    if (!cached_subvol) { -        gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", -                     loc->path); -        op_errno = EINVAL; -        goto err; -    } - -    local->flags = xflag; -    if (IA_ISREG(loc->inode->ia_type) && (hashed_subvol == cached_subvol)) { -        /* -         * File resides in cold tier. We need to stat -         * the file to see if it is being promoted. -         * If yes we need to delete the destination -         * file as well. -         * -         * Currently we are doing this check only for -         * regular files. -         */ -        xdata = xdata ? dict_ref(xdata) : dict_new(); -        if (xdata) { -            ret = dict_set_int8(xdata, DHT_IATT_IN_XDATA_KEY, 1); -            if (ret) { -                gf_msg_debug(this->name, 0, "Failed to set dictionary key %s", -                             DHT_IATT_IN_XDATA_KEY); -            } -        } -    } - -    /* -     * File is on hot tier, delete the data file first, then -     * linkfile from cold. -     */ -    STACK_WIND_COOKIE(frame, tier_unlink_cbk, cached_subvol, cached_subvol, -                      cached_subvol->fops->unlink, loc, xflag, xdata); -    if (xdata) -        dict_unref(xdata); -    return 0; -err: -    op_errno = (op_errno == -1) ? errno : op_errno; -    DHT_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); - -    return 0; -} - -int -tier_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                 int op_errno, gf_dirent_t *orig_entries, dict_t *xdata) -{ -    gf_dirent_t entries; -    gf_dirent_t *orig_entry = NULL; -    gf_dirent_t *entry = NULL; -    int count = 0; - -    INIT_LIST_HEAD(&entries.list); - -    if (op_ret < 0) -        goto unwind; - -    list_for_each_entry(orig_entry, (&orig_entries->list), list) -    { -        entry = gf_dirent_for_name(orig_entry->d_name); -        if (!entry) { -            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, -                   "Memory allocation failed "); -            goto unwind; -        } - -        entry->d_off = orig_entry->d_off; -        entry->d_ino = orig_entry->d_ino; -        entry->d_type = orig_entry->d_type; -        entry->d_len = orig_entry->d_len; - -        list_add_tail(&entry->list, &entries.list); -        count++; -    } -    op_ret = count; - -unwind: -    if (op_ret < 0) -        op_ret = 0; - -    DHT_STACK_UNWIND(readdir, frame, op_ret, op_errno, &entries, NULL); - -    gf_dirent_free(&entries); - -    return 0; -} - -int -tier_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                  int op_errno, gf_dirent_t *orig_entries, dict_t *xdata) -{ -    dht_local_t *local = NULL; -    gf_dirent_t entries; -    gf_dirent_t *orig_entry = NULL; -    gf_dirent_t *entry = NULL; -    xlator_t *prev = NULL; -    xlator_t *next_subvol = NULL; -    off_t next_offset = 0; -    int count = 0; -    dht_conf_t *conf = NULL; -    int ret = 0; -    inode_table_t *itable = NULL; -    inode_t *inode = NULL; - -    INIT_LIST_HEAD(&entries.list); -    prev = cookie; -    local = frame->local; -    itable = local->fd ? local->fd->inode->table : NULL; - -    conf = this->private; -    GF_VALIDATE_OR_GOTO(this->name, conf, unwind); - -    if (op_ret < 0) -        goto done; - -    list_for_each_entry(orig_entry, (&orig_entries->list), list) -    { -        next_offset = orig_entry->d_off; - -        if (IA_ISINVAL(orig_entry->d_stat.ia_type)) { -            /*stat failed somewhere- ignore this entry*/ -            continue; -        } - -        entry = gf_dirent_for_name(orig_entry->d_name); -        if (!entry) { -            goto unwind; -        } - -        entry->d_off = orig_entry->d_off; -        entry->d_stat = orig_entry->d_stat; -        entry->d_ino = orig_entry->d_ino; -        entry->d_type = orig_entry->d_type; -        entry->d_len = orig_entry->d_len; - -        if (orig_entry->dict) -            entry->dict = dict_ref(orig_entry->dict); - -        if (check_is_linkfile(NULL, (&orig_entry->d_stat), orig_entry->dict, -                              conf->link_xattr_name)) { -            goto entries; - -        } else if (IA_ISDIR(entry->d_stat.ia_type)) { -            if (orig_entry->inode) { -                dht_inode_ctx_time_update(orig_entry->inode, this, -                                          &entry->d_stat, 1); -            } -        } else { -            if (orig_entry->inode) { -                ret = dht_layout_preset(this, prev, orig_entry->inode); -                if (ret) -                    gf_msg(this->name, GF_LOG_WARNING, 0, -                           DHT_MSG_LAYOUT_SET_FAILED, -                           "failed to link the layout " -                           "in inode"); - -                entry->inode = inode_ref(orig_entry->inode); -            } else if (itable) { -                /* -                 * orig_entry->inode might be null if any upper -                 * layer xlators below client set to null, to -                 * force a lookup on the inode even if the inode -                 * is present in the inode table. In that case -                 * we just update the ctx to make sure we didn't -                 * missed anything. -                 */ -                inode = inode_find(itable, orig_entry->d_stat.ia_gfid); -                if (inode) { -                    ret = dht_layout_preset(this, TIER_HASHED_SUBVOL, inode); -                    if (ret) -                        gf_msg(this->name, GF_LOG_WARNING, 0, -                               DHT_MSG_LAYOUT_SET_FAILED, -                               "failed to link the layout" -                               " in inode"); -                    inode_unref(inode); -                    inode = NULL; -                } -            } -        } - -    entries: -        list_add_tail(&entry->list, &entries.list); -        count++; -    } -    op_ret = count; - -done: -    if (count == 0) { -        /* non-zero next_offset means that -           EOF is not yet hit on the current subvol -        */ -        if (next_offset != 0) { -            next_subvol = prev; -        } else { -            goto unwind; -        } - -        STACK_WIND_COOKIE(frame, tier_readdirp_cbk, next_subvol, next_subvol, -                          next_subvol->fops->readdirp, local->fd, local->size, -                          next_offset, local->xattr); -        return 0; -    } - -unwind: -    if (op_ret < 0) -        op_ret = 0; - -    DHT_STACK_UNWIND(readdirp, frame, op_ret, op_errno, &entries, NULL); - -    gf_dirent_free(&entries); - -    return 0; -} - -int -tier_do_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -                off_t yoff, int whichop, dict_t *dict) -{ -    dht_local_t *local = NULL; -    int op_errno = -1; -    xlator_t *hashed_subvol = NULL; -    int ret = 0; -    dht_conf_t *conf = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(this->private, err); - -    conf = this->private; - -    local = dht_local_init(frame, NULL, NULL, whichop); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    local->fd = fd_ref(fd); -    local->size = size; -    local->xattr_req = (dict) ? dict_ref(dict) : NULL; - -    hashed_subvol = TIER_HASHED_SUBVOL; - -    /* TODO: do proper readdir */ -    if (whichop == GF_FOP_READDIRP) { -        if (dict) -            local->xattr = dict_ref(dict); -        else -            local->xattr = dict_new(); - -        if (local->xattr) { -            ret = dict_set_uint32(local->xattr, conf->link_xattr_name, 256); -            if (ret) -                gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, -                       "Failed to set dictionary value" -                       " : key = %s", -                       conf->link_xattr_name); -        } - -        STACK_WIND_COOKIE(frame, tier_readdirp_cbk, hashed_subvol, -                          hashed_subvol, hashed_subvol->fops->readdirp, fd, -                          size, yoff, local->xattr); - -    } else { -        STACK_WIND_COOKIE(frame, tier_readdir_cbk, hashed_subvol, hashed_subvol, -                          hashed_subvol->fops->readdir, fd, size, yoff, -                          local->xattr); -    } - -    return 0; - -err: -    op_errno = (op_errno == -1) ? errno : op_errno; -    DHT_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); - -    return 0; -} - -int -tier_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -             off_t yoff, dict_t *xdata) -{ -    int op = GF_FOP_READDIR; -    dht_conf_t *conf = NULL; -    int i = 0; - -    conf = this->private; -    if (!conf) -        goto out; - -    for (i = 0; i < conf->subvolume_cnt; i++) { -        if (!conf->subvolume_status[i]) { -            op = GF_FOP_READDIRP; -            break; -        } -    } - -    if (conf->use_readdirp) -        op = GF_FOP_READDIRP; - -out: -    tier_do_readdir(frame, this, fd, size, yoff, op, 0); -    return 0; -} - -int -tier_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -              off_t yoff, dict_t *dict) -{ -    tier_do_readdir(frame, this, fd, size, yoff, GF_FOP_READDIRP, dict); -    return 0; -} - -int -tier_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                int op_errno, struct statvfs *statvfs, dict_t *xdata) -{ -    gf_boolean_t event = _gf_false; -    qdstatfs_action_t action = qdstatfs_action_OFF; -    dht_local_t *local = NULL; -    int this_call_cnt = 0; -    int bsize = 0; -    int frsize = 0; -    GF_UNUSED int ret = 0; -    unsigned long new_usage = 0; -    unsigned long cur_usage = 0; -    xlator_t *prev = NULL; -    dht_conf_t *conf = NULL; -    tier_statvfs_t *tier_stat = NULL; - -    prev = cookie; -    local = frame->local; -    GF_ASSERT(local); - -    conf = this->private; - -    if (xdata) -        ret = dict_get_int8(xdata, "quota-deem-statfs", (int8_t *)&event); - -    tier_stat = &local->tier_statvfs; - -    LOCK(&frame->lock); -    { -        if (op_ret == -1) { -            local->op_errno = op_errno; -            goto unlock; -        } -        if (!statvfs) { -            op_errno = EINVAL; -            local->op_ret = -1; -            goto unlock; -        } -        local->op_ret = 0; - -        if (local->quota_deem_statfs) { -            if (event == _gf_true) { -                action = qdstatfs_action_COMPARE; -            } else { -                action = qdstatfs_action_NEGLECT; -            } -        } else { -            if (event == _gf_true) { -                action = qdstatfs_action_REPLACE; -                local->quota_deem_statfs = _gf_true; -            } -        } - -        if (local->quota_deem_statfs) { -            switch (action) { -                case qdstatfs_action_NEGLECT: -                    goto unlock; - -                case qdstatfs_action_REPLACE: -                    local->statvfs = *statvfs; -                    goto unlock; - -                case qdstatfs_action_COMPARE: -                    new_usage = statvfs->f_blocks - statvfs->f_bfree; -                    cur_usage = local->statvfs.f_blocks - -                                local->statvfs.f_bfree; - -                    /* Take the max of the usage from subvols */ -                    if (new_usage >= cur_usage) -                        local->statvfs = *statvfs; -                    goto unlock; - -                default: -                    break; -            } -        } - -        if (local->statvfs.f_bsize != 0) { -            bsize = max(local->statvfs.f_bsize, statvfs->f_bsize); -            frsize = max(local->statvfs.f_frsize, statvfs->f_frsize); -            dht_normalize_stats(&local->statvfs, bsize, frsize); -            dht_normalize_stats(statvfs, bsize, frsize); -        } else { -            local->statvfs.f_bsize = statvfs->f_bsize; -            local->statvfs.f_frsize = statvfs->f_frsize; -        } - -        if (prev == TIER_HASHED_SUBVOL) { -            local->statvfs.f_blocks = statvfs->f_blocks; -            local->statvfs.f_files = statvfs->f_files; -            local->statvfs.f_fsid = statvfs->f_fsid; -            local->statvfs.f_flag = statvfs->f_flag; -            local->statvfs.f_namemax = statvfs->f_namemax; -            tier_stat->blocks_used = (statvfs->f_blocks - statvfs->f_bfree); -            tier_stat->pblocks_used = (statvfs->f_blocks - statvfs->f_bavail); -            tier_stat->files_used = (statvfs->f_files - statvfs->f_ffree); -            tier_stat->pfiles_used = (statvfs->f_files - statvfs->f_favail); -            tier_stat->hashed_fsid = statvfs->f_fsid; -        } else { -            tier_stat->unhashed_fsid = statvfs->f_fsid; -            tier_stat->unhashed_blocks_used = (statvfs->f_blocks - -                                               statvfs->f_bfree); -            tier_stat->unhashed_pblocks_used = (statvfs->f_blocks - -                                                statvfs->f_bavail); -            tier_stat->unhashed_files_used = (statvfs->f_files - -                                              statvfs->f_ffree); -            tier_stat->unhashed_pfiles_used = (statvfs->f_files - -                                               statvfs->f_favail); -        } -    } -unlock: -    UNLOCK(&frame->lock); - -    this_call_cnt = dht_frame_return(frame); -    if (is_last_call(this_call_cnt)) { -        if (tier_stat->unhashed_fsid != tier_stat->hashed_fsid) { -            tier_stat->blocks_used += tier_stat->unhashed_blocks_used; -            tier_stat->pblocks_used += tier_stat->unhashed_pblocks_used; -            tier_stat->files_used += tier_stat->unhashed_files_used; -            tier_stat->pfiles_used += tier_stat->unhashed_pfiles_used; -        } -        local->statvfs.f_bfree = local->statvfs.f_blocks - -                                 tier_stat->blocks_used; -        local->statvfs.f_bavail = local->statvfs.f_blocks - -                                  tier_stat->pblocks_used; -        local->statvfs.f_ffree = local->statvfs.f_files - tier_stat->files_used; -        local->statvfs.f_favail = local->statvfs.f_files - -                                  tier_stat->pfiles_used; -        DHT_STACK_UNWIND(statfs, frame, local->op_ret, local->op_errno, -                         &local->statvfs, xdata); -    } - -    return 0; -} - -int -tier_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    dht_local_t *local = NULL; -    dht_conf_t *conf = NULL; -    int op_errno = -1; -    int i = -1; -    inode_t *inode = NULL; -    inode_table_t *itable = NULL; -    uuid_t root_gfid = { -        0, -    }; -    loc_t newloc = { -        0, -    }; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(this->private, err); - -    conf = this->private; - -    local = dht_local_init(frame, NULL, NULL, GF_FOP_STATFS); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    if (loc->inode && !IA_ISDIR(loc->inode->ia_type)) { -        itable = loc->inode->table; -        if (!itable) { -            op_errno = EINVAL; -            goto err; -        } - -        loc = &local->loc2; -        root_gfid[15] = 1; - -        inode = inode_find(itable, root_gfid); -        if (!inode) { -            op_errno = EINVAL; -            goto err; -        } - -        dht_build_root_loc(inode, &newloc); -        loc = &newloc; -    } - -    local->call_cnt = conf->subvolume_cnt; - -    for (i = 0; i < conf->subvolume_cnt; i++) { -        STACK_WIND_COOKIE(frame, tier_statfs_cbk, conf->subvolumes[i], -                          conf->subvolumes[i], -                          conf->subvolumes[i]->fops->statfs, loc, xdata); -    } - -    return 0; - -err: -    op_errno = (op_errno == -1) ? errno : op_errno; -    DHT_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); - -    return 0; -} diff --git a/xlators/cluster/dht/src/tier-common.h b/xlators/cluster/dht/src/tier-common.h deleted file mode 100644 index b1ebaa8004d..00000000000 --- a/xlators/cluster/dht/src/tier-common.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -  Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _TIER_COMMON_H_ -#define _TIER_COMMON_H_ -/* Function definitions */ -int -tier_create_unlink_stale_linkto_cbk(call_frame_t *frame, void *cookie, -                                    xlator_t *this, int op_ret, int op_errno, -                                    struct iatt *preparent, -                                    struct iatt *postparent, dict_t *xdata); - -int -tier_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, -                struct iatt *preparent, struct iatt *postparent, dict_t *xdata); - -int -tier_create_linkfile_create_cbk(call_frame_t *frame, void *cookie, -                                xlator_t *this, int32_t op_ret, -                                int32_t op_errno, inode_t *inode, -                                struct iatt *stbuf, struct iatt *preparent, -                                struct iatt *postparent, dict_t *xdata); - -int -tier_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -            mode_t mode, mode_t umask, fd_t *fd, dict_t *params); - -int32_t -tier_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, -            dict_t *xdata); - -int32_t -tier_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -              off_t off, dict_t *dict); - -int -tier_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -             off_t yoff, dict_t *xdata); - -int -tier_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -          dict_t *xdata); - -int -tier_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); - -#endif diff --git a/xlators/cluster/dht/src/tier.c b/xlators/cluster/dht/src/tier.c deleted file mode 100644 index a8cccaf019e..00000000000 --- a/xlators/cluster/dht/src/tier.c +++ /dev/null @@ -1,3090 +0,0 @@ -/* -  Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <dlfcn.h> - -#include "dht-common.h" -#include "tier.h" -#include "tier-common.h" -#include <glusterfs/syscall.h> -#include <glusterfs/events.h> -#include "tier-ctr-interface.h" - -/*Hard coded DB info*/ -static gfdb_db_type_t dht_tier_db_type = GFDB_SQLITE3; -/*Hard coded DB info*/ - -/*Mutex for updating the data movement stats*/ -static pthread_mutex_t dm_stat_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* Stores the path location of promotion query files */ -static char *promotion_qfile; -/* Stores the path location of demotion query files */ -static char *demotion_qfile; - -static void *libhandle; -static gfdb_methods_t gfdb_methods; - -#define DB_QUERY_RECORD_SIZE 4096 - -/* - * Closes all the fds and frees the qfile_array - * */ -static void -qfile_array_free(tier_qfile_array_t *qfile_array) -{ -    ssize_t i = 0; - -    if (qfile_array) { -        if (qfile_array->fd_array) { -            for (i = 0; i < qfile_array->array_size; i++) { -                if (qfile_array->fd_array[i] != -1) { -                    sys_close(qfile_array->fd_array[i]); -                } -            } -        } -        GF_FREE(qfile_array->fd_array); -    } -    GF_FREE(qfile_array); -} - -/* Create a new query file list with given size */ -static tier_qfile_array_t * -qfile_array_new(ssize_t array_size) -{ -    int ret = -1; -    tier_qfile_array_t *qfile_array = NULL; -    ssize_t i = 0; - -    GF_VALIDATE_OR_GOTO("tier", (array_size > 0), out); - -    qfile_array = GF_CALLOC(1, sizeof(tier_qfile_array_t), -                            gf_tier_mt_qfile_array_t); -    if (!qfile_array) { -        gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to allocate memory for tier_qfile_array_t"); -        goto out; -    } - -    qfile_array->fd_array = GF_MALLOC(array_size * sizeof(int), -                                      gf_dht_mt_int32_t); -    if (!qfile_array->fd_array) { -        gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to allocate memory for " -               "tier_qfile_array_t->fd_array"); -        goto out; -    } - -    /* Init all the fds to -1 */ -    for (i = 0; i < array_size; i++) { -        qfile_array->fd_array[i] = -1; -    } - -    qfile_array->array_size = array_size; -    qfile_array->next_index = 0; - -    /* Set exhausted count to list size as the list is empty */ -    qfile_array->exhausted_count = qfile_array->array_size; - -    ret = 0; -out: -    if (ret) { -        qfile_array_free(qfile_array); -        qfile_array = NULL; -    } -    return qfile_array; -} - -/* Checks if the query file list is empty or totally exhausted. */ -static gf_boolean_t -is_qfile_array_empty(tier_qfile_array_t *qfile_array) -{ -    return (qfile_array->exhausted_count == qfile_array->array_size) -               ? _gf_true -               : _gf_false; -} - -/* Shifts the next_fd pointer to the next available fd in the list */ -static void -shift_next_index(tier_qfile_array_t *qfile_array) -{ -    int qfile_fd = 0; -    int spin_count = 0; - -    if (is_qfile_array_empty(qfile_array)) { -        return; -    } - -    do { -        /* change next_index in a rotional manner */ -        (qfile_array->next_index == (qfile_array->array_size - 1)) -            ? qfile_array->next_index = 0 -            : qfile_array->next_index++; - -        qfile_fd = (qfile_array->fd_array[qfile_array->next_index]); - -        spin_count++; - -    } while ((qfile_fd == -1) && (spin_count < qfile_array->array_size)); -} - -/* - * This is a non-thread safe function to read query records - * from a list of query files in a Round-Robin manner. - * As in when the query files get exhuasted they are closed. - * Returns: - * 0   if all the query records in all the query files of the list are - *     exhausted. - * > 0 if a query record is successfully read. Indicates the size of the query - *     record read. - * < 0  if there was failure - * */ -static int -read_query_record_list(tier_qfile_array_t *qfile_array, -                       gfdb_query_record_t **query_record) -{ -    int ret = -1; -    int qfile_fd = 0; - -    GF_VALIDATE_OR_GOTO("tier", qfile_array, out); -    GF_VALIDATE_OR_GOTO("tier", qfile_array->fd_array, out); - -    do { -        if (is_qfile_array_empty(qfile_array)) { -            ret = 0; -            break; -        } - -        qfile_fd = qfile_array->fd_array[qfile_array->next_index]; -        ret = gfdb_methods.gfdb_read_query_record(qfile_fd, query_record); -        if (ret <= 0) { -            /*The qfile_fd has reached EOF or -             * there was an error. -             * 1. Close the exhausted fd -             * 2. increment the exhausted count -             * 3. shift next_qfile to next qfile -             **/ -            sys_close(qfile_fd); -            qfile_array->fd_array[qfile_array->next_index] = -1; -            qfile_array->exhausted_count++; -            /* shift next_qfile to next qfile */ -            shift_next_index(qfile_array); -            continue; -        } else { -            /* shift next_qfile to next qfile */ -            shift_next_index(qfile_array); -            break; -        } -    } while (1); -out: -    return ret; -} - -/* Check and update the watermark every WM_INTERVAL seconds */ -#define WM_INTERVAL 5 -#define WM_INTERVAL_EMERG 1 - -static int -tier_check_same_node(xlator_t *this, loc_t *loc, gf_defrag_info_t *defrag) -{ -    int ret = -1; -    dict_t *dict = NULL; -    char *uuid_str = NULL; -    uuid_t node_uuid = { -        0, -    }; - -    GF_VALIDATE_OR_GOTO("tier", this, out); -    GF_VALIDATE_OR_GOTO(this->name, loc, out); -    GF_VALIDATE_OR_GOTO(this->name, defrag, out); - -    if (syncop_getxattr(this, loc, &dict, GF_XATTR_NODE_UUID_KEY, NULL, NULL)) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Unable to get NODE_UUID_KEY %s %s\n", loc->name, loc->path); -        goto out; -    } - -    if (dict_get_str(dict, GF_XATTR_NODE_UUID_KEY, &uuid_str) < 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to get node-uuids for %s", loc->path); -        goto out; -    } - -    if (gf_uuid_parse(uuid_str, node_uuid)) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "uuid_parse failed for %s", loc->path); -        goto out; -    } - -    if (gf_uuid_compare(node_uuid, defrag->node_uuid)) { -        gf_msg_debug(this->name, 0, "%s does not belong to this node", -                     loc->path); -        ret = 1; -        goto out; -    } - -    ret = 0; -out: -    if (dict) -        dict_unref(dict); - -    return ret; -} - -int -tier_get_fs_stat(xlator_t *this, loc_t *root_loc) -{ -    int ret = 0; -    gf_defrag_info_t *defrag = NULL; -    dht_conf_t *conf = NULL; -    dict_t *xdata = NULL; -    struct statvfs statfs = { -        0, -    }; -    gf_tier_conf_t *tier_conf = NULL; - -    conf = this->private; -    if (!conf) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_STATUS, -               "conf is NULL"); -        ret = -1; -        goto exit; -    } - -    defrag = conf->defrag; -    if (!defrag) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_STATUS, -               "defrag is NULL"); -        ret = -1; -        goto exit; -    } - -    tier_conf = &defrag->tier_conf; - -    xdata = dict_new(); -    if (!xdata) { -        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, -               "failed to allocate dictionary"); -        ret = -1; -        goto exit; -    } - -    ret = dict_set_int8(xdata, GF_INTERNAL_IGNORE_DEEM_STATFS, 1); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, -               "Failed to set " GF_INTERNAL_IGNORE_DEEM_STATFS " in dict"); -        ret = -1; -        goto exit; -    } - -    /* Find how much free space is on the hot subvolume. -     * Then see if that value */ -    /* is less than or greater than user defined watermarks. -     * Stash results in */ -    /* the tier_conf data structure. */ - -    ret = syncop_statfs(conf->subvolumes[1], root_loc, &statfs, xdata, NULL); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LOG_TIER_STATUS, -               "Unable to obtain statfs."); -        goto exit; -    } - -    pthread_mutex_lock(&dm_stat_mutex); - -    tier_conf->block_size = statfs.f_bsize; -    tier_conf->blocks_total = statfs.f_blocks; -    tier_conf->blocks_used = statfs.f_blocks - statfs.f_bfree; - -    tier_conf->percent_full = GF_PERCENTAGE(tier_conf->blocks_used, -                                            statfs.f_blocks); -    pthread_mutex_unlock(&dm_stat_mutex); - -exit: -    if (xdata) -        dict_unref(xdata); -    return ret; -} - -static void -tier_send_watermark_event(const char *volname, tier_watermark_op_t old_wm, -                          tier_watermark_op_t new_wm) -{ -    if (old_wm == TIER_WM_LOW || old_wm == TIER_WM_NONE) { -        if (new_wm == TIER_WM_MID) { -            gf_event(EVENT_TIER_WATERMARK_RAISED_TO_MID, "vol=%s", volname); -        } else if (new_wm == TIER_WM_HI) { -            gf_event(EVENT_TIER_WATERMARK_HI, "vol=%s", volname); -        } -    } else if (old_wm == TIER_WM_MID) { -        if (new_wm == TIER_WM_LOW) { -            gf_event(EVENT_TIER_WATERMARK_DROPPED_TO_LOW, "vol=%s", volname); -        } else if (new_wm == TIER_WM_HI) { -            gf_event(EVENT_TIER_WATERMARK_HI, "vol=%s", volname); -        } -    } else if (old_wm == TIER_WM_HI) { -        if (new_wm == TIER_WM_MID) { -            gf_event(EVENT_TIER_WATERMARK_DROPPED_TO_MID, "vol=%s", volname); -        } else if (new_wm == TIER_WM_LOW) { -            gf_event(EVENT_TIER_WATERMARK_DROPPED_TO_LOW, "vol=%s", volname); -        } -    } -} - -int -tier_check_watermark(xlator_t *this) -{ -    int ret = -1; -    gf_defrag_info_t *defrag = NULL; -    dht_conf_t *conf = NULL; -    gf_tier_conf_t *tier_conf = NULL; -    tier_watermark_op_t wm = TIER_WM_NONE; - -    conf = this->private; -    if (!conf) -        goto exit; - -    defrag = conf->defrag; -    if (!defrag) -        goto exit; - -    tier_conf = &defrag->tier_conf; - -    if (tier_conf->percent_full < tier_conf->watermark_low) { -        wm = TIER_WM_LOW; - -    } else if (tier_conf->percent_full < tier_conf->watermark_hi) { -        wm = TIER_WM_MID; - -    } else { -        wm = TIER_WM_HI; -    } - -    if (wm != tier_conf->watermark_last) { -        tier_send_watermark_event(tier_conf->volname, tier_conf->watermark_last, -                                  wm); - -        tier_conf->watermark_last = wm; -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "Tier watermark now %d", wm); -    } - -    ret = 0; - -exit: -    return ret; -} - -static gf_boolean_t -is_hot_tier_full(gf_tier_conf_t *tier_conf) -{ -    if (tier_conf && (tier_conf->mode == TIER_MODE_WM) && -        (tier_conf->watermark_last == TIER_WM_HI)) -        return _gf_true; - -    return _gf_false; -} - -int -tier_do_migration(xlator_t *this, int promote) -{ -    gf_defrag_info_t *defrag = NULL; -    dht_conf_t *conf = NULL; -    long rand = 0; -    int migrate = 0; -    gf_tier_conf_t *tier_conf = NULL; - -    conf = this->private; -    if (!conf) -        goto exit; - -    defrag = conf->defrag; -    if (!defrag) -        goto exit; - -    if (tier_check_watermark(this) != 0) { -        gf_msg(this->name, GF_LOG_CRITICAL, errno, DHT_MSG_LOG_TIER_ERROR, -               "Failed to get watermark"); -        goto exit; -    } - -    tier_conf = &defrag->tier_conf; - -    switch (tier_conf->watermark_last) { -        case TIER_WM_LOW: -            migrate = promote ? 1 : 0; -            break; -        case TIER_WM_HI: -            migrate = promote ? 0 : 1; -            break; -        case TIER_WM_MID: -            /* coverity[DC.WEAK_CRYPTO] */ -            rand = random() % 100; -            if (promote) { -                migrate = (rand > tier_conf->percent_full); -            } else { -                migrate = (rand <= tier_conf->percent_full); -            } -            break; -    } - -exit: -    return migrate; -} - -int -tier_migrate(xlator_t *this, int is_promotion, dict_t *migrate_data, loc_t *loc, -             gf_tier_conf_t *tier_conf) -{ -    int ret = -1; - -    pthread_mutex_lock(&tier_conf->pause_mutex); -    if (is_promotion) -        tier_conf->promote_in_progress = 1; -    else -        tier_conf->demote_in_progress = 1; -    pthread_mutex_unlock(&tier_conf->pause_mutex); - -    /* Data migration */ -    ret = syncop_setxattr(this, loc, migrate_data, 0, NULL, NULL); - -    pthread_mutex_lock(&tier_conf->pause_mutex); -    if (is_promotion) -        tier_conf->promote_in_progress = 0; -    else -        tier_conf->demote_in_progress = 0; -    pthread_mutex_unlock(&tier_conf->pause_mutex); - -    return ret; -} - -/* returns  _gf_true: if file can be promoted - * returns _gf_false: if file cannot be promoted - */ -static gf_boolean_t -tier_can_promote_file(xlator_t *this, char const *file_name, -                      struct iatt *current, gf_defrag_info_t *defrag) -{ -    gf_boolean_t ret = _gf_false; -    fsblkcnt_t estimated_usage = 0; - -    if (defrag->tier_conf.tier_max_promote_size && -        (current->ia_size > defrag->tier_conf.tier_max_promote_size)) { -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "File %s (gfid:%s) with size (%" PRIu64 -               ") exceeds maxsize " -               "(%d) for promotion. File will not be promoted.", -               file_name, uuid_utoa(current->ia_gfid), current->ia_size, -               defrag->tier_conf.tier_max_promote_size); -        goto err; -    } - -    /* bypass further validations for TEST mode */ -    if (defrag->tier_conf.mode != TIER_MODE_WM) { -        ret = _gf_true; -        goto err; -    } - -    /* convert the file size to blocks as per the block size of the -     * destination tier -     * NOTE: add (block_size - 1) to get the correct block size when -     *       there is a remainder after a modulo -     */ -    estimated_usage = ((current->ia_size + defrag->tier_conf.block_size - 1) / -                       defrag->tier_conf.block_size) + -                      defrag->tier_conf.blocks_used; - -    /* test if the estimated block usage goes above HI watermark */ -    if (GF_PERCENTAGE(estimated_usage, defrag->tier_conf.blocks_total) >= -        defrag->tier_conf.watermark_hi) { -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "Estimated block count consumption on " -               "hot tier (%" PRIu64 -               ") exceeds hi watermark (%d%%). " -               "File will not be promoted.", -               estimated_usage, defrag->tier_conf.watermark_hi); -        goto err; -    } -    ret = _gf_true; -err: -    return ret; -} - -static int -tier_set_migrate_data(dict_t *migrate_data) -{ -    int failed = 1; - -    failed = dict_set_str(migrate_data, GF_XATTR_FILE_MIGRATE_KEY, "force"); -    if (failed) { -        goto bail_out; -    } - -    /* Flag to suggest the xattr call is from migrator */ -    failed = dict_set_str(migrate_data, "from.migrator", "yes"); -    if (failed) { -        goto bail_out; -    } - -    /* Flag to suggest its a tiering migration -     * The reason for this dic key-value is that -     * promotions and demotions are multithreaded -     * so the original frame from gf_defrag_start() -     * is not carried. A new frame will be created when -     * we do syncop_setxattr(). This does not have the -     * frame->root->pid of the original frame. So we pass -     * this dic key-value when we do syncop_setxattr() to do -     * data migration and set the frame->root->pid to -     * GF_CLIENT_PID_TIER_DEFRAG in dht_setxattr() just before -     * calling dht_start_rebalance_task() */ -    failed = dict_set_str(migrate_data, TIERING_MIGRATION_KEY, "yes"); -    if (failed) { -        goto bail_out; -    } - -    failed = 0; - -bail_out: -    return failed; -} - -static char * -tier_get_parent_path(xlator_t *this, loc_t *p_loc, struct iatt *par_stbuf, -                     int *per_link_status) -{ -    int ret = -1; -    char *parent_path = NULL; -    dict_t *xdata_request = NULL; -    dict_t *xdata_response = NULL; - -    xdata_request = dict_new(); -    if (!xdata_request) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to create xdata_request dict"); -        goto err; -    } -    ret = dict_set_int32(xdata_request, GET_ANCESTRY_PATH_KEY, 42); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to set value to dict : key %s \n", -               GET_ANCESTRY_PATH_KEY); -        goto err; -    } - -    ret = syncop_lookup(this, p_loc, par_stbuf, NULL, xdata_request, -                        &xdata_response); -    /* When the parent gfid is a stale entry, the lookup -     * will fail and stop the demotion process. -     * The parent gfid can be stale when a huge folder is -     * deleted while the files within it are being migrated -     */ -    if (ret == -ESTALE) { -        gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_STALE_LOOKUP, -               "Stale entry in parent lookup for %s", uuid_utoa(p_loc->gfid)); -        *per_link_status = 1; -        goto err; -    } else if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LOG_TIER_ERROR, -               "Error in parent lookup for %s", uuid_utoa(p_loc->gfid)); -        *per_link_status = -1; -        goto err; -    } -    ret = dict_get_str(xdata_response, GET_ANCESTRY_PATH_KEY, &parent_path); -    if (ret || !parent_path) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to get parent path for %s", uuid_utoa(p_loc->gfid)); -        *per_link_status = -1; -        goto err; -    } - -err: -    if (xdata_request) { -        dict_unref(xdata_request); -    } - -    if (xdata_response) { -        dict_unref(xdata_response); -        xdata_response = NULL; -    } - -    return parent_path; -} - -static int -tier_get_file_name_and_path(xlator_t *this, uuid_t gfid, -                            gfdb_link_info_t *link_info, -                            char const *parent_path, loc_t *loc, -                            int *per_link_status) -{ -    int ret = -1; - -    loc->name = gf_strdup(link_info->file_name); -    if (!loc->name) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Memory " -               "allocation failed for %s", -               uuid_utoa(gfid)); -        *per_link_status = -1; -        goto err; -    } -    ret = gf_asprintf((char **)&(loc->path), "%s/%s", parent_path, loc->name); -    if (ret < 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to " -               "construct file path for %s %s\n", -               parent_path, loc->name); -        *per_link_status = -1; -        goto err; -    } - -    ret = 0; - -err: -    return ret; -} - -static int -tier_lookup_file(xlator_t *this, loc_t *p_loc, loc_t *loc, struct iatt *current, -                 int *per_link_status) -{ -    int ret = -1; - -    ret = syncop_lookup(this, loc, current, NULL, NULL, NULL); - -    /* The file may be deleted even when the parent -     * is available and the lookup will -     * return a stale entry which would stop the -     * migration. so if its a stale entry, then skip -     * the file and keep migrating. -     */ -    if (ret == -ESTALE) { -        gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_STALE_LOOKUP, -               "Stale lookup for %s", uuid_utoa(p_loc->gfid)); -        *per_link_status = 1; -        goto err; -    } else if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LOG_TIER_ERROR, -               "Failed to " -               "lookup file %s\n", -               loc->name); -        *per_link_status = -1; -        goto err; -    } -    ret = 0; - -err: -    return ret; -} - -static gf_boolean_t -tier_is_file_already_at_destination(xlator_t *src_subvol, -                                    query_cbk_args_t *query_cbk_args, -                                    dht_conf_t *conf, int *per_link_status) -{ -    gf_boolean_t at_destination = _gf_true; - -    if (src_subvol == NULL) { -        *per_link_status = 1; -        goto err; -    } -    if (query_cbk_args->is_promotion && src_subvol == conf->subvolumes[1]) { -        *per_link_status = 1; -        goto err; -    } - -    if (!query_cbk_args->is_promotion && src_subvol == conf->subvolumes[0]) { -        *per_link_status = 1; -        goto err; -    } -    at_destination = _gf_false; - -err: -    return at_destination; -} - -static void -tier_update_migration_counters(query_cbk_args_t *query_cbk_args, -                               gf_defrag_info_t *defrag, -                               uint64_t *total_migrated_bytes, int *total_files) -{ -    if (query_cbk_args->is_promotion) { -        defrag->total_files_promoted++; -        *total_migrated_bytes += defrag->tier_conf.st_last_promoted_size; -        pthread_mutex_lock(&dm_stat_mutex); -        defrag->tier_conf.blocks_used += defrag->tier_conf -                                             .st_last_promoted_size; -        pthread_mutex_unlock(&dm_stat_mutex); -    } else { -        defrag->total_files_demoted++; -        *total_migrated_bytes += defrag->tier_conf.st_last_demoted_size; -        pthread_mutex_lock(&dm_stat_mutex); -        defrag->tier_conf.blocks_used -= defrag->tier_conf.st_last_demoted_size; -        pthread_mutex_unlock(&dm_stat_mutex); -    } -    if (defrag->tier_conf.blocks_total) { -        pthread_mutex_lock(&dm_stat_mutex); -        defrag->tier_conf.percent_full = GF_PERCENTAGE( -            defrag->tier_conf.blocks_used, defrag->tier_conf.blocks_total); -        pthread_mutex_unlock(&dm_stat_mutex); -    } - -    (*total_files)++; -} - -static int -tier_migrate_link(xlator_t *this, dht_conf_t *conf, uuid_t gfid, -                  gfdb_link_info_t *link_info, gf_defrag_info_t *defrag, -                  query_cbk_args_t *query_cbk_args, dict_t *migrate_data, -                  int *per_link_status, int *total_files, -                  uint64_t *total_migrated_bytes) -{ -    int ret = -1; -    struct iatt current = { -        0, -    }; -    struct iatt par_stbuf = { -        0, -    }; -    loc_t p_loc = { -        0, -    }; -    loc_t loc = { -        0, -    }; -    xlator_t *src_subvol = NULL; -    inode_t *linked_inode = NULL; -    char *parent_path = NULL; - -    /* Lookup for parent and get the path of parent */ -    gf_uuid_copy(p_loc.gfid, link_info->pargfid); -    p_loc.inode = inode_new(defrag->root_inode->table); -    if (!p_loc.inode) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to create reference to inode" -               " for %s", -               uuid_utoa(p_loc.gfid)); - -        *per_link_status = -1; -        goto err; -    } - -    parent_path = tier_get_parent_path(this, &p_loc, &par_stbuf, -                                       per_link_status); -    if (!parent_path) { -        goto err; -    } - -    linked_inode = inode_link(p_loc.inode, NULL, NULL, &par_stbuf); -    inode_unref(p_loc.inode); -    p_loc.inode = linked_inode; - -    /* Preparing File Inode */ -    gf_uuid_copy(loc.gfid, gfid); -    loc.inode = inode_new(defrag->root_inode->table); -    gf_uuid_copy(loc.pargfid, link_info->pargfid); -    loc.parent = inode_ref(p_loc.inode); - -    /* Get filename and Construct file path */ -    if (tier_get_file_name_and_path(this, gfid, link_info, parent_path, &loc, -                                    per_link_status) != 0) { -        goto err; -    } -    gf_uuid_copy(loc.parent->gfid, link_info->pargfid); - -    /* lookup file inode */ -    if (tier_lookup_file(this, &p_loc, &loc, ¤t, per_link_status) != 0) { -        goto err; -    } - -    if (query_cbk_args->is_promotion) { -        if (!tier_can_promote_file(this, link_info->file_name, ¤t, -                                   defrag)) { -            *per_link_status = 1; -            goto err; -        } -    } - -    linked_inode = inode_link(loc.inode, NULL, NULL, ¤t); -    inode_unref(loc.inode); -    loc.inode = linked_inode; - -    /* -     * Do not promote/demote if file already is where it -     * should be. It means another brick moved the file -     * so is not an error. So we set per_link_status = 1 -     * so that we ignore counting this. -     */ -    src_subvol = dht_subvol_get_cached(this, loc.inode); - -    if (tier_is_file_already_at_destination(src_subvol, query_cbk_args, conf, -                                            per_link_status)) { -        goto err; -    } - -    gf_msg_debug(this->name, 0, "Tier %s: src_subvol %s file %s", -                 (query_cbk_args->is_promotion ? "promote" : "demote"), -                 src_subvol->name, loc.path); - -    ret = tier_check_same_node(this, &loc, defrag); -    if (ret != 0) { -        if (ret < 0) { -            *per_link_status = -1; -            goto err; -        } -        ret = 0; -        /* By setting per_link_status to 1 we are -         * ignoring this status and will not be counting -         * this file for migration */ -        *per_link_status = 1; -        goto err; -    } - -    gf_uuid_copy(loc.gfid, loc.inode->gfid); - -    if (gf_defrag_get_pause_state(&defrag->tier_conf) != TIER_RUNNING) { -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "Tiering paused. " -               "Exiting tier_migrate_link"); -        goto err; -    } - -    ret = tier_migrate(this, query_cbk_args->is_promotion, migrate_data, &loc, -                       &defrag->tier_conf); - -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LOG_TIER_ERROR, -               "Failed to " -               "migrate %s ", -               loc.path); -        *per_link_status = -1; -        goto err; -    } - -    tier_update_migration_counters(query_cbk_args, defrag, total_migrated_bytes, -                                   total_files); - -    ret = 0; - -err: -    GF_FREE((char *)loc.name); -    loc.name = NULL; -    loc_wipe(&loc); -    loc_wipe(&p_loc); - -    if ((*total_files >= defrag->tier_conf.max_migrate_files) || -        (*total_migrated_bytes > defrag->tier_conf.max_migrate_bytes)) { -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "Reached cycle migration limit." -               "migrated bytes %" PRId64 " files %d", -               *total_migrated_bytes, *total_files); -        ret = -1; -    } - -    return ret; -} - -static int -tier_migrate_using_query_file(void *_args) -{ -    int ret = -1; -    query_cbk_args_t *query_cbk_args = (query_cbk_args_t *)_args; -    xlator_t *this = NULL; -    gf_defrag_info_t *defrag = NULL; -    gfdb_query_record_t *query_record = NULL; -    gfdb_link_info_t *link_info = NULL; -    dict_t *migrate_data = NULL; -    /* -     * per_file_status and per_link_status -     *  0  : success -     * -1 : failure -     *  1  : ignore the status and don't count for migration -     * */ -    int per_file_status = 0; -    int per_link_status = 0; -    int total_status = 0; -    dht_conf_t *conf = NULL; -    uint64_t total_migrated_bytes = 0; -    int total_files = 0; -    loc_t root_loc = {0}; -    gfdb_time_t start_time = {0}; -    gfdb_time_t current_time = {0}; -    int total_time = 0; -    int max_time = 0; -    gf_boolean_t emergency_demote_mode = _gf_false; - -    GF_VALIDATE_OR_GOTO("tier", query_cbk_args, out); -    GF_VALIDATE_OR_GOTO("tier", query_cbk_args->this, out); -    this = query_cbk_args->this; -    GF_VALIDATE_OR_GOTO(this->name, query_cbk_args->defrag, out); -    GF_VALIDATE_OR_GOTO(this->name, query_cbk_args->qfile_array, out); -    GF_VALIDATE_OR_GOTO(this->name, this->private, out); - -    conf = this->private; - -    defrag = query_cbk_args->defrag; -    migrate_data = dict_new(); -    if (!migrate_data) -        goto out; - -    emergency_demote_mode = (!query_cbk_args->is_promotion && -                             is_hot_tier_full(&defrag->tier_conf)); - -    if (tier_set_migrate_data(migrate_data) != 0) { -        goto out; -    } - -    dht_build_root_loc(defrag->root_inode, &root_loc); - -    ret = gettimeofday(&start_time, NULL); -    if (query_cbk_args->is_promotion) { -        max_time = defrag->tier_conf.tier_promote_frequency; -    } else { -        max_time = defrag->tier_conf.tier_demote_frequency; -    } - -    /* Per file */ -    while ((ret = read_query_record_list(query_cbk_args->qfile_array, -                                         &query_record)) != 0) { -        if (ret < 0) { -            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                   "Failed to fetch query record " -                   "from query file"); -            goto out; -        } - -        if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { -            ret = -1; -            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                   "Exiting tier migration as" -                   "defrag status is not started"); -            goto out; -        } - -        ret = gettimeofday(¤t_time, NULL); -        if (ret < 0) { -            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                   "Could not get current time."); -            goto out; -        } - -        total_time = current_time.tv_sec - start_time.tv_sec; -        if (total_time > max_time) { -            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -                   "Max cycle time reached. Exiting migration."); -            goto out; -        } - -        per_file_status = 0; -        per_link_status = 0; - -        if (gf_defrag_get_pause_state(&defrag->tier_conf) != TIER_RUNNING) { -            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -                   "Tiering paused. " -                   "Exiting tier_migrate_using_query_file"); -            break; -        } - -        if (defrag->tier_conf.mode == TIER_MODE_WM) { -            ret = tier_get_fs_stat(this, &root_loc); -            if (ret != 0) { -                gfdb_methods.gfdb_query_record_free(query_record); -                query_record = NULL; -                gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_STATUS, -                       "tier_get_fs_stat() FAILED ... " -                       "skipping file migrations until next cycle"); -                break; -            } - -            if (!tier_do_migration(this, query_cbk_args->is_promotion)) { -                gfdb_methods.gfdb_query_record_free(query_record); -                query_record = NULL; - -                /* We have crossed the high watermark. Stop processing -                 * files if this is a promotion cycle so demotion gets -                 * a chance to start if not already running*/ - -                if (query_cbk_args->is_promotion && -                    is_hot_tier_full(&defrag->tier_conf)) { -                    gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -                           "High watermark crossed during " -                           "promotion. Exiting " -                           "tier_migrate_using_query_file"); -                    break; -                } -                continue; -            } -        } - -        per_link_status = 0; - -        /* For now we only support single link migration. And we will -         * ignore other hard links in the link info list of query record -         * TODO: Multiple hard links migration */ -        if (!list_empty(&query_record->link_list)) { -            link_info = list_first_entry(&query_record->link_list, -                                         gfdb_link_info_t, list); -        } -        if (link_info != NULL) { -            if (tier_migrate_link(this, conf, query_record->gfid, link_info, -                                  defrag, query_cbk_args, migrate_data, -                                  &per_link_status, &total_files, -                                  &total_migrated_bytes) != 0) { -                gf_msg( -                    this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -                    "%s failed for %s(gfid:%s)", -                    (query_cbk_args->is_promotion ? "Promotion" : "Demotion"), -                    link_info->file_name, uuid_utoa(query_record->gfid)); -            } -        } -        per_file_status = per_link_status; - -        if (per_file_status < 0) { /* Failure */ -            pthread_mutex_lock(&dm_stat_mutex); -            defrag->total_failures++; -            pthread_mutex_unlock(&dm_stat_mutex); -        } else if (per_file_status == 0) { /* Success */ -            pthread_mutex_lock(&dm_stat_mutex); -            defrag->total_files++; -            pthread_mutex_unlock(&dm_stat_mutex); -        } else if (per_file_status == 1) { /* Ignore */ -            per_file_status = 0; -            /* Since this attempt was ignored we -             * decrement the lookup count*/ -            pthread_mutex_lock(&dm_stat_mutex); -            defrag->num_files_lookedup--; -            pthread_mutex_unlock(&dm_stat_mutex); -        } -        total_status = total_status + per_file_status; -        per_link_status = 0; -        per_file_status = 0; - -        gfdb_methods.gfdb_query_record_free(query_record); -        query_record = NULL; - -        /* If we are demoting and the entry watermark was HI, then -         * we are done with emergency demotions if the current -         * watermark has fallen below hi-watermark level -         */ -        if (emergency_demote_mode) { -            if (tier_check_watermark(this) == 0) { -                if (!is_hot_tier_full(&defrag->tier_conf)) { -                    break; -                } -            } -        } -    } - -out: -    if (migrate_data) -        dict_unref(migrate_data); - -    gfdb_methods.gfdb_query_record_free(query_record); -    query_record = NULL; - -    return total_status; -} - -/* This is the call back function per record/file from data base */ -static int -tier_gf_query_callback(gfdb_query_record_t *gfdb_query_record, void *_args) -{ -    int ret = -1; -    query_cbk_args_t *query_cbk_args = _args; - -    GF_VALIDATE_OR_GOTO("tier", query_cbk_args, out); -    GF_VALIDATE_OR_GOTO("tier", query_cbk_args->defrag, out); -    GF_VALIDATE_OR_GOTO("tier", (query_cbk_args->query_fd > 0), out); - -    ret = gfdb_methods.gfdb_write_query_record(query_cbk_args->query_fd, -                                               gfdb_query_record); -    if (ret) { -        gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed writing query record to query file"); -        goto out; -    } - -    pthread_mutex_lock(&dm_stat_mutex); -    query_cbk_args->defrag->num_files_lookedup++; -    pthread_mutex_unlock(&dm_stat_mutex); - -    ret = 0; -out: -    return ret; -} - -/* Create query file in tier process */ -static int -tier_process_self_query(tier_brick_list_t *local_brick, void *args) -{ -    int ret = -1; -    char *db_path = NULL; -    query_cbk_args_t *query_cbk_args = NULL; -    xlator_t *this = NULL; -    gfdb_conn_node_t *conn_node = NULL; -    dict_t *params_dict = NULL; -    dict_t *ctr_ipc_dict = NULL; -    gfdb_brick_info_t *gfdb_brick_info = args; - -    /*Init of all the essentials*/ -    GF_VALIDATE_OR_GOTO("tier", gfdb_brick_info, out); -    query_cbk_args = gfdb_brick_info->_query_cbk_args; - -    GF_VALIDATE_OR_GOTO("tier", query_cbk_args->this, out); -    this = query_cbk_args->this; - -    GF_VALIDATE_OR_GOTO(this->name, gfdb_brick_info->_query_cbk_args, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick->xlator, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick->brick_db_path, out); - -    db_path = local_brick->brick_db_path; - -    /*Preparing DB parameters before init_db i.e getting db connection*/ -    params_dict = dict_new(); -    if (!params_dict) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "DB Params cannot initialized"); -        goto out; -    } -    SET_DB_PARAM_TO_DICT(this->name, params_dict, -                         (char *)gfdb_methods.get_db_path_key(), db_path, ret, -                         out); - -    /*Get the db connection*/ -    conn_node = gfdb_methods.init_db((void *)params_dict, dht_tier_db_type); -    if (!conn_node) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "FATAL: Failed initializing db operations"); -        goto out; -    } - -    /* Query for eligible files from db */ -    query_cbk_args->query_fd = open(local_brick->qfile_path, -                                    O_WRONLY | O_CREAT | O_APPEND, -                                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -    if (query_cbk_args->query_fd < 0) { -        gf_msg(this->name, GF_LOG_ERROR, errno, DHT_MSG_LOG_TIER_ERROR, -               "Failed to open query file %s", local_brick->qfile_path); -        goto out; -    } -    if (!gfdb_brick_info->_gfdb_promote) { -        if (query_cbk_args->defrag->tier_conf.watermark_last == TIER_WM_HI) { -            /* emergency demotion mode */ -            ret = gfdb_methods.find_all( -                conn_node, tier_gf_query_callback, (void *)query_cbk_args, -                query_cbk_args->defrag->tier_conf.query_limit); -        } else { -            if (query_cbk_args->defrag->write_freq_threshold == 0 && -                query_cbk_args->defrag->read_freq_threshold == 0) { -                ret = gfdb_methods.find_unchanged_for_time( -                    conn_node, tier_gf_query_callback, (void *)query_cbk_args, -                    gfdb_brick_info->time_stamp); -            } else { -                ret = gfdb_methods.find_unchanged_for_time_freq( -                    conn_node, tier_gf_query_callback, (void *)query_cbk_args, -                    gfdb_brick_info->time_stamp, -                    query_cbk_args->defrag->write_freq_threshold, -                    query_cbk_args->defrag->read_freq_threshold, _gf_false); -            } -        } -    } else { -        if (query_cbk_args->defrag->write_freq_threshold == 0 && -            query_cbk_args->defrag->read_freq_threshold == 0) { -            ret = gfdb_methods.find_recently_changed_files( -                conn_node, tier_gf_query_callback, (void *)query_cbk_args, -                gfdb_brick_info->time_stamp); -        } else { -            ret = gfdb_methods.find_recently_changed_files_freq( -                conn_node, tier_gf_query_callback, (void *)query_cbk_args, -                gfdb_brick_info->time_stamp, -                query_cbk_args->defrag->write_freq_threshold, -                query_cbk_args->defrag->read_freq_threshold, _gf_false); -        } -    } -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "FATAL: query from db failed"); -        goto out; -    } - -    /*Clear the heat on the DB entries*/ -    /*Preparing ctr_ipc_dict*/ -    ctr_ipc_dict = dict_new(); -    if (!ctr_ipc_dict) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "ctr_ipc_dict cannot initialized"); -        goto out; -    } - -    SET_DB_PARAM_TO_DICT(this->name, ctr_ipc_dict, GFDB_IPC_CTR_KEY, -                         GFDB_IPC_CTR_CLEAR_OPS, ret, out); - -    ret = syncop_ipc(local_brick->xlator, GF_IPC_TARGET_CTR, ctr_ipc_dict, -                     NULL); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed clearing the heat " -               "on db %s error %d", -               local_brick->brick_db_path, ret); -        goto out; -    } - -    ret = 0; -out: -    if (params_dict) { -        dict_unref(params_dict); -        params_dict = NULL; -    } - -    if (ctr_ipc_dict) { -        dict_unref(ctr_ipc_dict); -        ctr_ipc_dict = NULL; -    } - -    if (query_cbk_args && query_cbk_args->query_fd >= 0) { -        sys_close(query_cbk_args->query_fd); -        query_cbk_args->query_fd = -1; -    } -    gfdb_methods.fini_db(conn_node); - -    return ret; -} - -/*Ask CTR to create the query file*/ -static int -tier_process_ctr_query(tier_brick_list_t *local_brick, void *args) -{ -    int ret = -1; -    query_cbk_args_t *query_cbk_args = NULL; -    xlator_t *this = NULL; -    dict_t *ctr_ipc_in_dict = NULL; -    dict_t *ctr_ipc_out_dict = NULL; -    gfdb_brick_info_t *gfdb_brick_info = args; -    gfdb_ipc_ctr_params_t *ipc_ctr_params = NULL; -    int count = 0; - -    /*Init of all the essentials*/ -    GF_VALIDATE_OR_GOTO("tier", gfdb_brick_info, out); -    query_cbk_args = gfdb_brick_info->_query_cbk_args; - -    GF_VALIDATE_OR_GOTO("tier", query_cbk_args->this, out); -    this = query_cbk_args->this; - -    GF_VALIDATE_OR_GOTO(this->name, gfdb_brick_info->_query_cbk_args, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick->xlator, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick->brick_db_path, out); - -    /*Preparing ctr_ipc_in_dict*/ -    ctr_ipc_in_dict = dict_new(); -    if (!ctr_ipc_in_dict) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "ctr_ipc_in_dict cannot initialized"); -        goto out; -    } - -    ipc_ctr_params = GF_CALLOC(1, sizeof(gfdb_ipc_ctr_params_t), -                               gf_tier_mt_ipc_ctr_params_t); -    if (!ipc_ctr_params) { -        goto out; -    } - -    /* set all the query params*/ -    ipc_ctr_params->is_promote = gfdb_brick_info->_gfdb_promote; - -    ipc_ctr_params->write_freq_threshold = query_cbk_args->defrag -                                               ->write_freq_threshold; - -    ipc_ctr_params->read_freq_threshold = query_cbk_args->defrag -                                              ->read_freq_threshold; - -    ipc_ctr_params->query_limit = query_cbk_args->defrag->tier_conf.query_limit; - -    ipc_ctr_params->emergency_demote = (!gfdb_brick_info->_gfdb_promote && -                                        query_cbk_args->defrag->tier_conf -                                                .watermark_last == TIER_WM_HI); - -    memcpy(&ipc_ctr_params->time_stamp, gfdb_brick_info->time_stamp, -           sizeof(gfdb_time_t)); - -    SET_DB_PARAM_TO_DICT(this->name, ctr_ipc_in_dict, GFDB_IPC_CTR_KEY, -                         GFDB_IPC_CTR_QUERY_OPS, ret, out); - -    SET_DB_PARAM_TO_DICT(this->name, ctr_ipc_in_dict, -                         GFDB_IPC_CTR_GET_QFILE_PATH, local_brick->qfile_path, -                         ret, out); - -    ret = dict_set_bin(ctr_ipc_in_dict, GFDB_IPC_CTR_GET_QUERY_PARAMS, -                       ipc_ctr_params, sizeof(*ipc_ctr_params)); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_SET_PARAM_FAILED, -               "Failed setting %s to params dictionary", -               GFDB_IPC_CTR_GET_QUERY_PARAMS); -        GF_FREE(ipc_ctr_params); -        goto out; -    } -    ipc_ctr_params = NULL; - -    ret = syncop_ipc(local_brick->xlator, GF_IPC_TARGET_CTR, ctr_ipc_in_dict, -                     &ctr_ipc_out_dict); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_IPC_TIER_ERROR, -               "Failed query on %s ret %d", local_brick->brick_db_path, ret); -        goto out; -    } - -    ret = dict_get_int32(ctr_ipc_out_dict, GFDB_IPC_CTR_RET_QUERY_COUNT, -                         &count); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed getting count " -               "of records on %s", -               local_brick->brick_db_path); -        goto out; -    } - -    if (count < 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed query on %s", local_brick->brick_db_path); -        ret = -1; -        goto out; -    } - -    pthread_mutex_lock(&dm_stat_mutex); -    query_cbk_args->defrag->num_files_lookedup = count; -    pthread_mutex_unlock(&dm_stat_mutex); - -    ret = 0; -out: - -    if (ctr_ipc_in_dict) { -        dict_unref(ctr_ipc_in_dict); -        ctr_ipc_in_dict = NULL; -    } - -    if (ctr_ipc_out_dict) { -        dict_unref(ctr_ipc_out_dict); -        ctr_ipc_out_dict = NULL; -    } - -    GF_FREE(ipc_ctr_params); - -    return ret; -} - -/* This is the call back function for each brick from hot/cold bricklist - * It picks up each bricks db and queries for eligible files for migration. - * The list of eligible files are populated in appropriate query files*/ -static int -tier_process_brick(tier_brick_list_t *local_brick, void *args) -{ -    int ret = -1; -    dict_t *ctr_ipc_in_dict = NULL; -    dict_t *ctr_ipc_out_dict = NULL; -    char *strval = NULL; - -    GF_VALIDATE_OR_GOTO("tier", local_brick, out); - -    GF_VALIDATE_OR_GOTO("tier", local_brick->xlator, out); - -    if (dht_tier_db_type == GFDB_SQLITE3) { -        /*Preparing ctr_ipc_in_dict*/ -        ctr_ipc_in_dict = dict_new(); -        if (!ctr_ipc_in_dict) { -            gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                   "ctr_ipc_in_dict cannot initialized"); -            goto out; -        } - -        ret = dict_set_str(ctr_ipc_in_dict, GFDB_IPC_CTR_KEY, -                           GFDB_IPC_CTR_GET_DB_PARAM_OPS); -        if (ret) { -            gf_msg("tier", GF_LOG_ERROR, 0, LG_MSG_SET_PARAM_FAILED, -                   "Failed to set %s " -                   "to params dictionary", -                   GFDB_IPC_CTR_KEY); -            goto out; -        } - -        ret = dict_set_str(ctr_ipc_in_dict, GFDB_IPC_CTR_GET_DB_PARAM_OPS, ""); -        if (ret) { -            gf_msg("tier", GF_LOG_ERROR, 0, LG_MSG_SET_PARAM_FAILED, -                   "Failed to set %s " -                   "to params dictionary", -                   GFDB_IPC_CTR_GET_DB_PARAM_OPS); -            goto out; -        } - -        ret = dict_set_str(ctr_ipc_in_dict, GFDB_IPC_CTR_GET_DB_KEY, -                           "journal_mode"); -        if (ret) { -            gf_msg("tier", GF_LOG_ERROR, 0, LG_MSG_SET_PARAM_FAILED, -                   "Failed to set %s " -                   "to params dictionary", -                   GFDB_IPC_CTR_GET_DB_KEY); -            goto out; -        } - -        ret = syncop_ipc(local_brick->xlator, GF_IPC_TARGET_CTR, -                         ctr_ipc_in_dict, &ctr_ipc_out_dict); -        if (ret || ctr_ipc_out_dict == NULL) { -            gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                   "Failed to get " -                   "journal_mode of sql db %s", -                   local_brick->brick_db_path); -            goto out; -        } - -        ret = dict_get_str(ctr_ipc_out_dict, "journal_mode", &strval); -        if (ret) { -            gf_msg("tier", GF_LOG_ERROR, 0, LG_MSG_GET_PARAM_FAILED, -                   "Failed to get %s " -                   "from params dictionary" -                   "journal_mode", -                   strval); -            goto out; -        } - -        if (strval && (strncmp(strval, "wal", SLEN("wal")) == 0)) { -            ret = tier_process_self_query(local_brick, args); -            if (ret) { -                goto out; -            } -        } else { -            ret = tier_process_ctr_query(local_brick, args); -            if (ret) { -                goto out; -            } -        } -        ret = 0; - -    } else { -        ret = tier_process_self_query(local_brick, args); -        if (ret) { -            goto out; -        } -    } - -    ret = 0; -out: -    if (ctr_ipc_in_dict) -        dict_unref(ctr_ipc_in_dict); - -    if (ctr_ipc_out_dict) -        dict_unref(ctr_ipc_out_dict); - -    return ret; -} - -static int -tier_build_migration_qfile(migration_args_t *args, -                           query_cbk_args_t *query_cbk_args, -                           gf_boolean_t is_promotion) -{ -    gfdb_time_t current_time; -    gfdb_brick_info_t gfdb_brick_info; -    gfdb_time_t time_in_past; -    int ret = -1; -    tier_brick_list_t *local_brick = NULL; -    int i = 0; -    time_in_past.tv_sec = args->freq_time; -    time_in_past.tv_usec = 0; - -    ret = gettimeofday(¤t_time, NULL); -    if (ret == -1) { -        gf_msg(args->this->name, GF_LOG_ERROR, errno, -               DHT_MSG_SYS_CALL_GET_TIME_FAILED, "Failed to get current time"); -        goto out; -    } -    time_in_past.tv_sec = current_time.tv_sec - time_in_past.tv_sec; - -    /* The migration daemon may run a varying numberof usec after the */ -    /* sleep call triggers. A file may be registered in CTR some number */ -    /* of usec X after the daemon started and missed in the subsequent */ -    /* cycle if the daemon starts Y usec after the period in seconds */ -    /* where Y>X. Normalize away this problem by always setting usec */ -    /* to 0. */ -    time_in_past.tv_usec = 0; - -    gfdb_brick_info.time_stamp = &time_in_past; -    gfdb_brick_info._gfdb_promote = is_promotion; -    gfdb_brick_info._query_cbk_args = query_cbk_args; - -    list_for_each_entry(local_brick, args->brick_list, list) -    { -        /* Construct query file path for this brick -         * i.e -         * /var/run/gluster/xlator_name/ -         * {promote/demote}-brickname-indexinbricklist -         * So that no two query files will have same path even -         * bricks have the same name -         * */ -        snprintf(local_brick->qfile_path, PATH_MAX, "%s-%s-%d", -                 GET_QFILE_PATH(gfdb_brick_info._gfdb_promote), -                 local_brick->brick_name, i); - -        /* Delete any old query files for this brick */ -        sys_unlink(local_brick->qfile_path); - -        ret = tier_process_brick(local_brick, &gfdb_brick_info); -        if (ret) { -            gf_msg(args->this->name, GF_LOG_ERROR, 0, -                   DHT_MSG_BRICK_QUERY_FAILED, "Brick %s query failed\n", -                   local_brick->brick_db_path); -        } -        i++; -    } -    ret = 0; -out: -    return ret; -} - -static int -tier_migrate_files_using_qfile(migration_args_t *comp, -                               query_cbk_args_t *query_cbk_args) -{ -    int ret = -1; -    tier_brick_list_t *local_brick = NULL; -    tier_brick_list_t *temp = NULL; -    gfdb_time_t current_time = { -        0, -    }; -    ssize_t qfile_array_size = 0; -    int count = 0; -    int temp_fd = 0; -    gf_tier_conf_t *tier_conf = NULL; - -    tier_conf = &(query_cbk_args->defrag->tier_conf); - -    /* Time for error query files */ -    gettimeofday(¤t_time, NULL); - -    /* Build the qfile list */ -    list_for_each_entry_safe(local_brick, temp, comp->brick_list, list) -    { -        qfile_array_size++; -    } -    query_cbk_args->qfile_array = qfile_array_new(qfile_array_size); -    if (!query_cbk_args->qfile_array) { -        gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to create new " -               "qfile_array"); -        goto out; -    } - -    /*Open all qfiles*/ -    count = 0; -    query_cbk_args->qfile_array->exhausted_count = 0; -    list_for_each_entry_safe(local_brick, temp, comp->brick_list, list) -    { -        temp_fd = query_cbk_args->qfile_array->fd_array[count]; -        temp_fd = open(local_brick->qfile_path, O_RDONLY, -                       S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -        if (temp_fd < 0) { -            gf_msg("tier", GF_LOG_ERROR, errno, DHT_MSG_LOG_TIER_ERROR, -                   "Failed to open " -                   "%s to the query file", -                   local_brick->qfile_path); -            query_cbk_args->qfile_array->exhausted_count++; -        } -        query_cbk_args->qfile_array->fd_array[count] = temp_fd; -        count++; -    } - -    /* Moving the query file index to the next, so that we won't the same -     * query file every cycle as the first one */ -    query_cbk_args->qfile_array -        ->next_index = (query_cbk_args->is_promotion) -                           ? tier_conf->last_promote_qfile_index -                           : tier_conf->last_demote_qfile_index; -    shift_next_index(query_cbk_args->qfile_array); -    if (query_cbk_args->is_promotion) { -        tier_conf->last_promote_qfile_index = query_cbk_args->qfile_array -                                                  ->next_index; -    } else { -        tier_conf->last_demote_qfile_index = query_cbk_args->qfile_array -                                                 ->next_index; -    } - -    /* Migrate files using query file list */ -    ret = tier_migrate_using_query_file((void *)query_cbk_args); -out: -    qfile_array_free(query_cbk_args->qfile_array); - -    /* If there is an error rename all the query files to .err files -     * with a timestamp for better debugging */ -    if (ret) { -        struct tm tm = { -            0, -        }; -        char time_str[128] = { -            0, -        }; -        char query_file_path_err[PATH_MAX] = { -            0, -        }; -        int32_t len = 0; - -        /* Time format for error query files */ -        gmtime_r(¤t_time.tv_sec, &tm); -        strftime(time_str, sizeof(time_str), "%F-%T", &tm); - -        list_for_each_entry_safe(local_brick, temp, comp->brick_list, list) -        { -            /* rename error qfile*/ -            len = snprintf(query_file_path_err, sizeof(query_file_path_err), -                           "%s-%s.err", local_brick->qfile_path, time_str); -            if ((len >= 0) && (len < sizeof(query_file_path_err))) { -                if (sys_rename(local_brick->qfile_path, query_file_path_err) == -                    -1) -                    gf_msg_debug("tier", 0, -                                 "rename " -                                 "failed"); -            } -        } -    } - -    query_cbk_args->qfile_array = NULL; - -    return ret; -} - -int -tier_demote(migration_args_t *demotion_args) -{ -    query_cbk_args_t query_cbk_args; -    int ret = -1; - -    GF_VALIDATE_OR_GOTO("tier", demotion_args, out); -    GF_VALIDATE_OR_GOTO("tier", demotion_args->this, out); -    GF_VALIDATE_OR_GOTO(demotion_args->this->name, demotion_args->brick_list, -                        out); -    GF_VALIDATE_OR_GOTO(demotion_args->this->name, demotion_args->defrag, out); - -    THIS = demotion_args->this; - -    query_cbk_args.this = demotion_args->this; -    query_cbk_args.defrag = demotion_args->defrag; -    query_cbk_args.is_promotion = 0; - -    /*Build the query file using bricklist*/ -    ret = tier_build_migration_qfile(demotion_args, &query_cbk_args, _gf_false); -    if (ret) -        goto out; - -    /* Migrate files using the query file */ -    ret = tier_migrate_files_using_qfile(demotion_args, &query_cbk_args); -    if (ret) -        goto out; - -out: -    demotion_args->return_value = ret; -    return ret; -} - -int -tier_promote(migration_args_t *promotion_args) -{ -    int ret = -1; -    query_cbk_args_t query_cbk_args; - -    GF_VALIDATE_OR_GOTO("tier", promotion_args->this, out); -    GF_VALIDATE_OR_GOTO(promotion_args->this->name, promotion_args->brick_list, -                        out); -    GF_VALIDATE_OR_GOTO(promotion_args->this->name, promotion_args->defrag, -                        out); - -    THIS = promotion_args->this; - -    query_cbk_args.this = promotion_args->this; -    query_cbk_args.defrag = promotion_args->defrag; -    query_cbk_args.is_promotion = 1; - -    /*Build the query file using bricklist*/ -    ret = tier_build_migration_qfile(promotion_args, &query_cbk_args, _gf_true); -    if (ret) -        goto out; - -    /* Migrate files using the query file */ -    ret = tier_migrate_files_using_qfile(promotion_args, &query_cbk_args); -    if (ret) -        goto out; - -out: -    promotion_args->return_value = ret; -    return ret; -} - -/* - * Command the CTR on a brick to compact the local database using an IPC - */ -static int -tier_process_self_compact(tier_brick_list_t *local_brick, void *args) -{ -    int ret = -1; -    char *db_path = NULL; -    query_cbk_args_t *query_cbk_args = NULL; -    xlator_t *this = NULL; -    gfdb_conn_node_t *conn_node = NULL; -    dict_t *params_dict = NULL; -    dict_t *ctr_ipc_dict = NULL; -    gfdb_brick_info_t *gfdb_brick_info = args; - -    /*Init of all the essentials*/ -    GF_VALIDATE_OR_GOTO("tier", gfdb_brick_info, out); -    query_cbk_args = gfdb_brick_info->_query_cbk_args; - -    GF_VALIDATE_OR_GOTO("tier", query_cbk_args->this, out); -    this = query_cbk_args->this; - -    GF_VALIDATE_OR_GOTO(this->name, gfdb_brick_info->_query_cbk_args, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick->xlator, out); - -    GF_VALIDATE_OR_GOTO(this->name, local_brick->brick_db_path, out); - -    db_path = local_brick->brick_db_path; - -    /*Preparing DB parameters before init_db i.e getting db connection*/ -    params_dict = dict_new(); -    if (!params_dict) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "DB Params cannot initialized"); -        goto out; -    } -    SET_DB_PARAM_TO_DICT(this->name, params_dict, -                         (char *)gfdb_methods.get_db_path_key(), db_path, ret, -                         out); - -    /*Get the db connection*/ -    conn_node = gfdb_methods.init_db((void *)params_dict, dht_tier_db_type); -    if (!conn_node) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "FATAL: Failed initializing db operations"); -        goto out; -    } - -    ret = 0; - -    /*Preparing ctr_ipc_dict*/ -    ctr_ipc_dict = dict_new(); -    if (!ctr_ipc_dict) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "ctr_ipc_dict cannot initialized"); -        goto out; -    } - -    ret = dict_set_int32(ctr_ipc_dict, "compact_active", -                         query_cbk_args->defrag->tier_conf.compact_active); - -    if (ret) { -        gf_msg("tier", GF_LOG_ERROR, 0, LG_MSG_SET_PARAM_FAILED, -               "Failed to set %s " -               "to params dictionary", -               "compact_active"); -        goto out; -    } - -    ret = dict_set_int32( -        ctr_ipc_dict, "compact_mode_switched", -        query_cbk_args->defrag->tier_conf.compact_mode_switched); - -    if (ret) { -        gf_msg("tier", GF_LOG_ERROR, 0, LG_MSG_SET_PARAM_FAILED, -               "Failed to set %s " -               "to params dictionary", -               "compact_mode_switched"); -        goto out; -    } - -    SET_DB_PARAM_TO_DICT(this->name, ctr_ipc_dict, GFDB_IPC_CTR_KEY, -                         GFDB_IPC_CTR_SET_COMPACT_PRAGMA, ret, out); - -    gf_msg(this->name, GF_LOG_TRACE, 0, DHT_MSG_LOG_TIER_STATUS, -           "Starting Compaction IPC"); - -    ret = syncop_ipc(local_brick->xlator, GF_IPC_TARGET_CTR, ctr_ipc_dict, -                     NULL); - -    gf_msg(this->name, GF_LOG_TRACE, 0, DHT_MSG_LOG_TIER_STATUS, -           "Ending Compaction IPC"); - -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed compaction " -               "on db %s error %d", -               local_brick->brick_db_path, ret); -        goto out; -    } - -    gf_msg(this->name, GF_LOG_TRACE, 0, DHT_MSG_LOG_TIER_STATUS, -           "SUCCESS: %s Compaction", local_brick->brick_name); - -    ret = 0; -out: -    if (params_dict) { -        dict_unref(params_dict); -        params_dict = NULL; -    } - -    if (ctr_ipc_dict) { -        dict_unref(ctr_ipc_dict); -        ctr_ipc_dict = NULL; -    } - -    gfdb_methods.fini_db(conn_node); - -    return ret; -} - -/* - * This is the call back function for each brick from hot/cold bricklist. - * It determines the database type on each brick and calls the corresponding - * function to prepare the compaction IPC. - */ -static int -tier_compact_db_brick(tier_brick_list_t *local_brick, void *args) -{ -    int ret = -1; - -    GF_VALIDATE_OR_GOTO("tier", local_brick, out); - -    GF_VALIDATE_OR_GOTO("tier", local_brick->xlator, out); - -    ret = tier_process_self_compact(local_brick, args); -    if (ret) { -        gf_msg("tier", GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "Brick %s did not compact", local_brick->brick_name); -        goto out; -    } - -    ret = 0; - -out: - -    return ret; -} - -static int -tier_send_compact(migration_args_t *args, query_cbk_args_t *query_cbk_args) -{ -    gfdb_time_t current_time; -    gfdb_brick_info_t gfdb_brick_info; -    gfdb_time_t time_in_past; -    int ret = -1; -    tier_brick_list_t *local_brick = NULL; - -    time_in_past.tv_sec = args->freq_time; -    time_in_past.tv_usec = 0; - -    ret = gettimeofday(¤t_time, NULL); -    if (ret == -1) { -        gf_msg(args->this->name, GF_LOG_ERROR, errno, -               DHT_MSG_SYS_CALL_GET_TIME_FAILED, "Failed to get current time"); -        goto out; -    } -    time_in_past.tv_sec = current_time.tv_sec - time_in_past.tv_sec; - -    /* The migration daemon may run a varying numberof usec after the sleep -       call triggers. A file may be registered in CTR some number of usec X -       after the daemon started and missed in the subsequent cycle if the -       daemon starts Y usec after the period in seconds where Y>X. Normalize -       away this problem by always setting usec to 0. */ -    time_in_past.tv_usec = 0; - -    gfdb_brick_info.time_stamp = &time_in_past; - -    /* This is meant to say we are always compacting at this point */ -    /* We simply borrow the promotion flag to do this */ -    gfdb_brick_info._gfdb_promote = 1; - -    gfdb_brick_info._query_cbk_args = query_cbk_args; - -    list_for_each_entry(local_brick, args->brick_list, list) -    { -        gf_msg(args->this->name, GF_LOG_TRACE, 0, DHT_MSG_LOG_TIER_STATUS, -               "Start compaction for %s", local_brick->brick_name); - -        ret = tier_compact_db_brick(local_brick, &gfdb_brick_info); -        if (ret) { -            gf_msg(args->this->name, GF_LOG_ERROR, 0, -                   DHT_MSG_BRICK_QUERY_FAILED, "Brick %s compaction failed\n", -                   local_brick->brick_db_path); -        } - -        gf_msg(args->this->name, GF_LOG_TRACE, 0, DHT_MSG_LOG_TIER_STATUS, -               "End compaction for %s", local_brick->brick_name); -    } -    ret = 0; -out: -    return ret; -} - -static int -tier_compact(void *args) -{ -    int ret = -1; -    query_cbk_args_t query_cbk_args; -    migration_args_t *compaction_args = args; - -    GF_VALIDATE_OR_GOTO("tier", compaction_args->this, out); -    GF_VALIDATE_OR_GOTO(compaction_args->this->name, -                        compaction_args->brick_list, out); -    GF_VALIDATE_OR_GOTO(compaction_args->this->name, compaction_args->defrag, -                        out); - -    THIS = compaction_args->this; - -    query_cbk_args.this = compaction_args->this; -    query_cbk_args.defrag = compaction_args->defrag; -    query_cbk_args.is_compaction = 1; - -    /* Send the compaction pragma out to all the bricks on the bricklist. */ -    /* tier_get_bricklist ensures all bricks on the list are local to */ -    /* this node. */ -    ret = tier_send_compact(compaction_args, &query_cbk_args); -    if (ret) -        goto out; - -    ret = 0; -out: -    compaction_args->return_value = ret; -    return ret; -} - -static int -tier_get_bricklist(xlator_t *xl, struct list_head *local_bricklist_head) -{ -    xlator_list_t *child = NULL; -    char *rv = NULL; -    char *rh = NULL; -    char *brickname = NULL; -    char db_name[PATH_MAX] = ""; -    int ret = 0; -    tier_brick_list_t *local_brick = NULL; -    int32_t len = 0; - -    GF_VALIDATE_OR_GOTO("tier", xl, out); -    GF_VALIDATE_OR_GOTO("tier", local_bricklist_head, out); - -    /* -     * This function obtains remote subvolumes and filters out only -     * those running on the same node as the tier daemon. -     */ -    if (strcmp(xl->type, "protocol/client") == 0) { -        ret = dict_get_str(xl->options, "remote-host", &rh); -        if (ret < 0) -            goto out; - -        if (gf_is_local_addr(rh)) { -            local_brick = GF_CALLOC(1, sizeof(tier_brick_list_t), -                                    gf_tier_mt_bricklist_t); -            if (!local_brick) { -                goto out; -            } - -            ret = dict_get_str(xl->options, "remote-subvolume", &rv); -            if (ret < 0) -                goto out; - -            brickname = strrchr(rv, '/') + 1; -            snprintf(db_name, sizeof(db_name), "%s.db", brickname); - -            local_brick->brick_db_path = GF_MALLOC(PATH_MAX, gf_common_mt_char); -            if (!local_brick->brick_db_path) { -                gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_STATUS, -                       "Failed to allocate memory for" -                       " bricklist."); -                ret = -1; -                goto out; -            } - -            len = snprintf(local_brick->brick_db_path, PATH_MAX, "%s/%s/%s", rv, -                           GF_HIDDEN_PATH, db_name); -            if ((len < 0) || (len >= PATH_MAX)) { -                gf_msg("tier", GF_LOG_ERROR, EINVAL, DHT_MSG_LOG_TIER_STATUS, -                       "DB path too long"); -                ret = -1; -                goto out; -            } - -            local_brick->xlator = xl; - -            snprintf(local_brick->brick_name, NAME_MAX, "%s", brickname); - -            list_add_tail(&(local_brick->list), local_bricklist_head); - -            ret = 0; -            goto out; -        } -    } - -    for (child = xl->children; child; child = child->next) { -        ret = tier_get_bricklist(child->xlator, local_bricklist_head); -        if (ret) { -            goto out; -        } -    } - -    ret = 0; -out: - -    if (ret) { -        if (local_brick) { -            GF_FREE(local_brick->brick_db_path); -        } -        GF_FREE(local_brick); -    } - -    return ret; -} - -int -tier_get_freq_demote(gf_tier_conf_t *tier_conf) -{ -    if ((tier_conf->mode == TIER_MODE_WM) && -        (tier_conf->watermark_last == TIER_WM_HI)) -        return DEFAULT_DEMOTE_DEGRADED; -    else -        return tier_conf->tier_demote_frequency; -} - -int -tier_get_freq_promote(gf_tier_conf_t *tier_conf) -{ -    return tier_conf->tier_promote_frequency; -} - -int -tier_get_freq_compact_hot(gf_tier_conf_t *tier_conf) -{ -    return tier_conf->tier_compact_hot_frequency; -} - -int -tier_get_freq_compact_cold(gf_tier_conf_t *tier_conf) -{ -    return tier_conf->tier_compact_cold_frequency; -} - -static int -tier_check_demote(gfdb_time_t current_time, int freq) -{ -    return ((current_time.tv_sec % freq) == 0) ? _gf_true : _gf_false; -} - -static gf_boolean_t -tier_check_promote(gf_tier_conf_t *tier_conf, gfdb_time_t current_time, -                   int freq) -{ -    if ((tier_conf->mode == TIER_MODE_WM) && -        (tier_conf->watermark_last == TIER_WM_HI)) -        return _gf_false; - -    else -        return ((current_time.tv_sec % freq) == 0) ? _gf_true : _gf_false; -} - -static gf_boolean_t -tier_check_compact(gf_tier_conf_t *tier_conf, gfdb_time_t current_time, -                   int freq_compact) -{ -    if (!(tier_conf->compact_active || tier_conf->compact_mode_switched)) -        return _gf_false; - -    return ((current_time.tv_sec % freq_compact) == 0) ? _gf_true : _gf_false; -} - -void -clear_bricklist(struct list_head *brick_list) -{ -    tier_brick_list_t *local_brick = NULL; -    tier_brick_list_t *temp = NULL; - -    if (list_empty(brick_list)) { -        return; -    } - -    list_for_each_entry_safe(local_brick, temp, brick_list, list) -    { -        list_del(&local_brick->list); -        GF_FREE(local_brick->brick_db_path); -        GF_FREE(local_brick); -    } -} - -static void -set_brick_list_qpath(struct list_head *brick_list, gf_boolean_t is_cold) -{ -    tier_brick_list_t *local_brick = NULL; -    int i = 0; - -    GF_VALIDATE_OR_GOTO("tier", brick_list, out); - -    list_for_each_entry(local_brick, brick_list, list) -    { -        /* Construct query file path for this brick -         * i.e -         * /var/run/gluster/xlator_name/ -         * {promote/demote}-brickname-indexinbricklist -         * So that no two query files will have same path even -         * bricks have the same name -         * */ -        snprintf(local_brick->qfile_path, PATH_MAX, "%s-%s-%d", -                 GET_QFILE_PATH(is_cold), local_brick->brick_name, i); -        i++; -    } -out: -    return; -} - -static int -tier_prepare_compact(migration_args_t *args, gfdb_time_t current_time) -{ -    xlator_t *this = NULL; -    dht_conf_t *conf = NULL; -    gf_defrag_info_t *defrag = NULL; -    gf_tier_conf_t *tier_conf = NULL; -    gf_boolean_t is_hot_tier = args->is_hot_tier; -    int freq = 0; -    int ret = -1; -    const char *tier_type = is_hot_tier ? "hot" : "cold"; - -    this = args->this; - -    conf = this->private; - -    defrag = conf->defrag; - -    tier_conf = &defrag->tier_conf; - -    freq = is_hot_tier ? tier_get_freq_compact_hot(tier_conf) -                       : tier_get_freq_compact_cold(tier_conf); - -    defrag->tier_conf.compact_mode_switched = -        is_hot_tier ? defrag->tier_conf.compact_mode_switched_hot -                    : defrag->tier_conf.compact_mode_switched_cold; - -    gf_msg(this->name, GF_LOG_TRACE, 0, DHT_MSG_LOG_TIER_STATUS, -           "Compact mode %i", defrag->tier_conf.compact_mode_switched); - -    if (tier_check_compact(tier_conf, current_time, freq)) { -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "Start compaction on %s tier", tier_type); - -        args->freq_time = freq; -        ret = tier_compact(args); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                   "Compaction failed on " -                   "%s tier", -                   tier_type); -            goto out; -        } - -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -               "End compaction on %s tier", tier_type); - -        if (is_hot_tier) { -            defrag->tier_conf.compact_mode_switched_hot = _gf_false; -        } else { -            defrag->tier_conf.compact_mode_switched_cold = _gf_false; -        } -    } - -out: -    return ret; -} - -static int -tier_get_wm_interval(tier_mode_t mode, tier_watermark_op_t wm) -{ -    if (mode == TIER_MODE_WM && wm == TIER_WM_HI) -        return WM_INTERVAL_EMERG; - -    return WM_INTERVAL; -} - -/* - * Main tiering loop. This is called from the promotion and the - * demotion threads spawned in tier_start(). - * - * Every second, wake from sleep to perform tasks. - * 1. Check trigger to migrate data. - * 2. Check for state changes (pause, unpause, stop). - */ -static void * -tier_run(void *in_args) -{ -    dht_conf_t *conf = NULL; -    gfdb_time_t current_time = {0}; -    int freq = 0; -    int ret = 0; -    xlator_t *any = NULL; -    xlator_t *xlator = NULL; -    gf_tier_conf_t *tier_conf = NULL; -    loc_t root_loc = {0}; -    int check_watermark = 0; -    gf_defrag_info_t *defrag = NULL; -    xlator_t *this = NULL; -    migration_args_t *args = in_args; -    GF_VALIDATE_OR_GOTO("tier", args, out); -    GF_VALIDATE_OR_GOTO("tier", args->brick_list, out); - -    this = args->this; -    GF_VALIDATE_OR_GOTO("tier", this, out); - -    conf = this->private; -    GF_VALIDATE_OR_GOTO("tier", conf, out); - -    defrag = conf->defrag; -    GF_VALIDATE_OR_GOTO("tier", defrag, out); - -    if (list_empty(args->brick_list)) { -        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_ERROR, -               "Brick list for tier is empty. Exiting."); -        goto out; -    } - -    defrag->defrag_status = GF_DEFRAG_STATUS_STARTED; -    tier_conf = &defrag->tier_conf; - -    dht_build_root_loc(defrag->root_inode, &root_loc); - -    while (1) { -        /* -         * Check if a graph switch occurred. If so, stop migration -         * thread. It will need to be restarted manually. -         */ -        any = THIS->ctx->active->first; -        xlator = xlator_search_by_name(any, this->name); - -        if (xlator != this) { -            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -                   "Detected graph switch. Exiting migration " -                   "daemon."); -            goto out; -        } - -        gf_defrag_check_pause_tier(tier_conf); - -        sleep(1); - -        if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { -            ret = 1; -            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                   "defrag->defrag_status != " -                   "GF_DEFRAG_STATUS_STARTED"); -            goto out; -        } - -        if (defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER || -            defrag->cmd == GF_DEFRAG_CMD_DETACH_START) { -            ret = 0; -            defrag->defrag_status = GF_DEFRAG_STATUS_COMPLETE; -            gf_msg(this->name, GF_LOG_DEBUG, 0, DHT_MSG_LOG_TIER_ERROR, -                   "defrag->defrag_cmd == " -                   "GF_DEFRAG_CMD_START_DETACH_TIER"); -            goto out; -        } - -        if (gf_defrag_get_pause_state(&defrag->tier_conf) != TIER_RUNNING) -            continue; - -        /* To have proper synchronization amongst all -         * brick holding nodes, so that promotion and demotions -         * start atomically w.r.t promotion/demotion frequency -         * period, all nodes should have their system time -         * in-sync with each other either manually set or -         * using a NTP server*/ -        ret = gettimeofday(¤t_time, NULL); -        if (ret == -1) { -            gf_msg(this->name, GF_LOG_ERROR, errno, -                   DHT_MSG_SYS_CALL_GET_TIME_FAILED, -                   "Failed to get current time"); -            goto out; -        } - -        check_watermark++; - -        /* emergency demotion requires frequent watermark monitoring */ -        if (check_watermark >= -            tier_get_wm_interval(tier_conf->mode, tier_conf->watermark_last)) { -            check_watermark = 0; -            if (tier_conf->mode == TIER_MODE_WM) { -                ret = tier_get_fs_stat(this, &root_loc); -                if (ret != 0) { -                    continue; -                } -                ret = tier_check_watermark(this); -                if (ret != 0) { -                    gf_msg(this->name, GF_LOG_CRITICAL, errno, -                           DHT_MSG_LOG_TIER_ERROR, "Failed to get watermark"); -                    continue; -                } -            } -        } - -        if (args->is_promotion) { -            freq = tier_get_freq_promote(tier_conf); - -            if (tier_check_promote(tier_conf, current_time, freq)) { -                args->freq_time = freq; -                ret = tier_promote(args); -                if (ret) { -                    gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                           "Promotion failed"); -                } -            } -        } else if (args->is_compaction) { -            tier_prepare_compact(args, current_time); -        } else { -            freq = tier_get_freq_demote(tier_conf); - -            if (tier_check_demote(current_time, freq)) { -                args->freq_time = freq; -                ret = tier_demote(args); -                if (ret) { -                    gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                           "Demotion failed"); -                } -            } -        } - -        /* Check the statfs immediately after the processing threads -           return */ -        check_watermark = WM_INTERVAL; -    } - -    ret = 0; -out: - -    args->return_value = ret; - -    return NULL; -} - -int -tier_start(xlator_t *this, gf_defrag_info_t *defrag) -{ -    pthread_t promote_thread; -    pthread_t demote_thread; -    pthread_t hot_compact_thread; -    pthread_t cold_compact_thread; -    int ret = -1; -    struct list_head bricklist_hot = {0}; -    struct list_head bricklist_cold = {0}; -    migration_args_t promotion_args = {0}; -    migration_args_t demotion_args = {0}; -    migration_args_t hot_compaction_args = {0}; -    migration_args_t cold_compaction_args = {0}; -    dht_conf_t *conf = NULL; - -    INIT_LIST_HEAD((&bricklist_hot)); -    INIT_LIST_HEAD((&bricklist_cold)); - -    conf = this->private; - -    tier_get_bricklist(conf->subvolumes[1], &bricklist_hot); -    set_brick_list_qpath(&bricklist_hot, _gf_false); - -    demotion_args.this = this; -    demotion_args.brick_list = &bricklist_hot; -    demotion_args.defrag = defrag; -    demotion_args.is_promotion = _gf_false; -    demotion_args.is_compaction = _gf_false; - -    ret = gf_thread_create(&demote_thread, NULL, &tier_run, &demotion_args, -                           "tierdem"); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to start demotion thread."); -        defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; -        goto cleanup; -    } - -    tier_get_bricklist(conf->subvolumes[0], &bricklist_cold); -    set_brick_list_qpath(&bricklist_cold, _gf_true); - -    promotion_args.this = this; -    promotion_args.brick_list = &bricklist_cold; -    promotion_args.defrag = defrag; -    promotion_args.is_promotion = _gf_true; - -    ret = gf_thread_create(&promote_thread, NULL, &tier_run, &promotion_args, -                           "tierpro"); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to start promotion thread."); -        defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; -        goto waitforspawned; -    } - -    hot_compaction_args.this = this; -    hot_compaction_args.brick_list = &bricklist_hot; -    hot_compaction_args.defrag = defrag; -    hot_compaction_args.is_promotion = _gf_false; -    hot_compaction_args.is_compaction = _gf_true; -    hot_compaction_args.is_hot_tier = _gf_true; - -    ret = gf_thread_create(&hot_compact_thread, NULL, &tier_run, -                           &hot_compaction_args, "tierhcom"); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to start compaction thread."); -        defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; -        goto waitforspawnedpromote; -    } - -    cold_compaction_args.this = this; -    cold_compaction_args.brick_list = &bricklist_cold; -    cold_compaction_args.defrag = defrag; -    cold_compaction_args.is_promotion = _gf_false; -    cold_compaction_args.is_compaction = _gf_true; -    cold_compaction_args.is_hot_tier = _gf_false; - -    ret = gf_thread_create(&cold_compact_thread, NULL, &tier_run, -                           &cold_compaction_args, "tierccom"); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Failed to start compaction thread."); -        defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; -        goto waitforspawnedhotcompact; -    } -    pthread_join(cold_compact_thread, NULL); - -waitforspawnedhotcompact: -    pthread_join(hot_compact_thread, NULL); - -waitforspawnedpromote: -    pthread_join(promote_thread, NULL); - -waitforspawned: -    pthread_join(demote_thread, NULL); - -cleanup: -    clear_bricklist(&bricklist_cold); -    clear_bricklist(&bricklist_hot); -    return ret; -} - -int32_t -tier_migration_needed(xlator_t *this) -{ -    gf_defrag_info_t *defrag = NULL; -    dht_conf_t *conf = NULL; -    int ret = 0; - -    conf = this->private; - -    GF_VALIDATE_OR_GOTO(this->name, conf, out); -    GF_VALIDATE_OR_GOTO(this->name, conf->defrag, out); - -    defrag = conf->defrag; - -    if ((defrag->cmd == GF_DEFRAG_CMD_START_TIER) || -        (defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER)) -        ret = 1; -out: -    return ret; -} - -int32_t -tier_migration_get_dst(xlator_t *this, dht_local_t *local) -{ -    dht_conf_t *conf = NULL; -    int32_t ret = -1; -    gf_defrag_info_t *defrag = NULL; - -    GF_VALIDATE_OR_GOTO("tier", this, out); -    GF_VALIDATE_OR_GOTO(this->name, this->private, out); - -    conf = this->private; - -    defrag = conf->defrag; - -    if (defrag && defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER) { -        local->rebalance.target_node = conf->subvolumes[0]; - -    } else if (conf->subvolumes[0] == local->cached_subvol) -        local->rebalance.target_node = conf->subvolumes[1]; -    else -        local->rebalance.target_node = conf->subvolumes[0]; - -    if (local->rebalance.target_node) -        ret = 0; - -out: -    return ret; -} - -xlator_t * -tier_search(xlator_t *this, dht_layout_t *layout, const char *name) -{ -    xlator_t *subvol = NULL; -    dht_conf_t *conf = NULL; - -    GF_VALIDATE_OR_GOTO("tier", this, out); -    GF_VALIDATE_OR_GOTO(this->name, this->private, out); - -    conf = this->private; - -    subvol = TIER_HASHED_SUBVOL; - -out: -    return subvol; -} - -static int -tier_load_externals(xlator_t *this) -{ -    int ret = -1; -    char *libpathfull = (LIBDIR "/libgfdb.so.0"); -    get_gfdb_methods_t get_gfdb_methods; - -    GF_VALIDATE_OR_GOTO("this", this, out); - -    libhandle = dlopen(libpathfull, RTLD_NOW); -    if (!libhandle) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Error loading libgfdb.so %s\n", dlerror()); -        ret = -1; -        goto out; -    } - -    get_gfdb_methods = dlsym(libhandle, "get_gfdb_methods"); -    if (!get_gfdb_methods) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Error loading get_gfdb_methods()"); -        ret = -1; -        goto out; -    } - -    get_gfdb_methods(&gfdb_methods); - -    ret = 0; - -out: -    if (ret && libhandle) -        dlclose(libhandle); - -    return ret; -} - -static tier_mode_t -tier_validate_mode(char *mode) -{ -    int ret = -1; - -    if (strcmp(mode, "test") == 0) { -        ret = TIER_MODE_TEST; -    } else { -        ret = TIER_MODE_WM; -    } - -    return ret; -} - -static gf_boolean_t -tier_validate_compact_mode(char *mode) -{ -    gf_boolean_t ret = _gf_false; - -    gf_msg("tier", GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -           "tier_validate_compact_mode: mode = %s", mode); - -    if (!strcmp(mode, "on")) { -        ret = _gf_true; -    } else { -        ret = _gf_false; -    } - -    gf_msg("tier", GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_STATUS, -           "tier_validate_compact_mode: ret = %i", ret); - -    return ret; -} - -int -tier_init_methods(xlator_t *this) -{ -    int ret = -1; -    dht_conf_t *conf = NULL; -    dht_methods_t *methods = NULL; - -    GF_VALIDATE_OR_GOTO("tier", this, err); - -    conf = this->private; - -    methods = &(conf->methods); - -    methods->migration_get_dst_subvol = tier_migration_get_dst; -    methods->migration_other = tier_start; -    methods->migration_needed = tier_migration_needed; -    methods->layout_search = tier_search; - -    ret = 0; -err: -    return ret; -} - -static void -tier_save_vol_name(xlator_t *this) -{ -    dht_conf_t *conf = NULL; -    gf_defrag_info_t *defrag = NULL; -    char *suffix = NULL; -    int name_len = 0; - -    conf = this->private; -    defrag = conf->defrag; - -    suffix = strstr(this->name, "-tier-dht"); - -    if (suffix) -        name_len = suffix - this->name; -    else -        name_len = strlen(this->name); - -    if (name_len > GD_VOLUME_NAME_MAX) -        name_len = GD_VOLUME_NAME_MAX; - -    strncpy(defrag->tier_conf.volname, this->name, name_len); -    defrag->tier_conf.volname[name_len] = 0; -} - -int -tier_init(xlator_t *this) -{ -    int ret = -1; -    int freq = 0; -    int maxsize = 0; -    dht_conf_t *conf = NULL; -    gf_defrag_info_t *defrag = NULL; -    char *voldir = NULL; -    char *mode = NULL; -    char *paused = NULL; -    tier_mode_t tier_mode = DEFAULT_TIER_MODE; -    gf_boolean_t compact_mode = _gf_false; - -    ret = dht_init(this); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "tier_init failed"); -        goto out; -    } - -    conf = this->private; - -    ret = tier_init_methods(this); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "tier_init_methods failed"); -        goto out; -    } - -    if (conf->subvolume_cnt != 2) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Invalid number of subvolumes %d", conf->subvolume_cnt); -        goto out; -    } - -    /* if instatiated from client side initialization is complete. */ -    if (!conf->defrag) { -        ret = 0; -        goto out; -    } - -    /* if instatiated from server side, load db libraries */ -    ret = tier_load_externals(this); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "Could not load externals. Aborting"); -        goto out; -    } - -    defrag = conf->defrag; - -    defrag->tier_conf.last_demote_qfile_index = 0; -    defrag->tier_conf.last_promote_qfile_index = 0; - -    defrag->tier_conf.is_tier = 1; -    defrag->this = this; - -    ret = dict_get_int32(this->options, "tier-max-promote-file-size", &maxsize); -    if (ret) { -        maxsize = 0; -    } - -    defrag->tier_conf.tier_max_promote_size = maxsize; - -    ret = dict_get_int32(this->options, "tier-promote-frequency", &freq); -    if (ret) { -        freq = DEFAULT_PROMOTE_FREQ_SEC; -    } - -    defrag->tier_conf.tier_promote_frequency = freq; - -    ret = dict_get_int32(this->options, "tier-demote-frequency", &freq); -    if (ret) { -        freq = DEFAULT_DEMOTE_FREQ_SEC; -    } - -    defrag->tier_conf.tier_demote_frequency = freq; - -    ret = dict_get_int32(this->options, "tier-hot-compact-frequency", &freq); -    if (ret) { -        freq = DEFAULT_HOT_COMPACT_FREQ_SEC; -    } - -    defrag->tier_conf.tier_compact_hot_frequency = freq; - -    ret = dict_get_int32(this->options, "tier-cold-compact-frequency", &freq); -    if (ret) { -        freq = DEFAULT_COLD_COMPACT_FREQ_SEC; -    } - -    defrag->tier_conf.tier_compact_cold_frequency = freq; - -    ret = dict_get_int32(this->options, "watermark-hi", &freq); -    if (ret) { -        freq = DEFAULT_WM_HI; -    } - -    defrag->tier_conf.watermark_hi = freq; - -    ret = dict_get_int32(this->options, "watermark-low", &freq); -    if (ret) { -        freq = DEFAULT_WM_LOW; -    } - -    defrag->tier_conf.watermark_low = freq; - -    ret = dict_get_int32(this->options, "write-freq-threshold", &freq); -    if (ret) { -        freq = DEFAULT_WRITE_FREQ_SEC; -    } - -    defrag->write_freq_threshold = freq; - -    ret = dict_get_int32(this->options, "read-freq-threshold", &freq); -    if (ret) { -        freq = DEFAULT_READ_FREQ_SEC; -    } - -    defrag->read_freq_threshold = freq; - -    ret = dict_get_int32(this->options, "tier-max-mb", &freq); -    if (ret) { -        freq = DEFAULT_TIER_MAX_MIGRATE_MB; -    } - -    defrag->tier_conf.max_migrate_bytes = (uint64_t)freq * 1024 * 1024; - -    ret = dict_get_int32(this->options, "tier-max-files", &freq); -    if (ret) { -        freq = DEFAULT_TIER_MAX_MIGRATE_FILES; -    } - -    defrag->tier_conf.max_migrate_files = freq; - -    ret = dict_get_int32(this->options, "tier-query-limit", -                         &(defrag->tier_conf.query_limit)); -    if (ret) { -        defrag->tier_conf.query_limit = DEFAULT_TIER_QUERY_LIMIT; -    } - -    ret = dict_get_str(this->options, "tier-compact", &mode); - -    if (ret) { -        defrag->tier_conf.compact_active = DEFAULT_COMP_MODE; -    } else { -        compact_mode = tier_validate_compact_mode(mode); -        /* If compaction is now active, we need to inform the bricks on -           the hot and cold tier of this. See dht-common.h for more. */ -        defrag->tier_conf.compact_active = compact_mode; -        if (compact_mode) { -            defrag->tier_conf.compact_mode_switched_hot = _gf_true; -            defrag->tier_conf.compact_mode_switched_cold = _gf_true; -        } -    } - -    ret = dict_get_str(this->options, "tier-mode", &mode); -    if (ret) { -        defrag->tier_conf.mode = DEFAULT_TIER_MODE; -    } else { -        tier_mode = tier_validate_mode(mode); -        defrag->tier_conf.mode = tier_mode; -    } - -    pthread_mutex_init(&defrag->tier_conf.pause_mutex, 0); - -    gf_defrag_set_pause_state(&defrag->tier_conf, TIER_RUNNING); - -    ret = dict_get_str(this->options, "tier-pause", &paused); - -    if (paused && strcmp(paused, "on") == 0) -        gf_defrag_set_pause_state(&defrag->tier_conf, TIER_REQUEST_PAUSE); - -    ret = gf_asprintf(&voldir, "%s/%s", DEFAULT_VAR_RUN_DIRECTORY, this->name); -    if (ret < 0) -        goto out; - -    ret = mkdir_p(voldir, 0777, _gf_true); -    if (ret == -1 && errno != EEXIST) { -        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -               "tier_init failed"); - -        GF_FREE(voldir); -        goto out; -    } - -    GF_FREE(voldir); - -    ret = gf_asprintf(&promotion_qfile, "%s/%s/promote", -                      DEFAULT_VAR_RUN_DIRECTORY, this->name); -    if (ret < 0) -        goto out; - -    ret = gf_asprintf(&demotion_qfile, "%s/%s/demote", -                      DEFAULT_VAR_RUN_DIRECTORY, this->name); -    if (ret < 0) { -        GF_FREE(promotion_qfile); -        goto out; -    } - -    gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -           "Promote/demote frequency %d/%d " -           "Write/Read freq thresholds %d/%d", -           defrag->tier_conf.tier_promote_frequency, -           defrag->tier_conf.tier_demote_frequency, -           defrag->write_freq_threshold, defrag->read_freq_threshold); - -    tier_save_vol_name(this); - -    ret = 0; - -out: - -    return ret; -} - -int -tier_cli_pause_done(int op_ret, call_frame_t *sync_frame, void *data) -{ -    gf_msg("tier", GF_LOG_INFO, 0, DHT_MSG_TIER_PAUSED, -           "Migrate file paused with op_ret %d", op_ret); - -    return op_ret; -} - -int -tier_cli_pause(void *data) -{ -    gf_defrag_info_t *defrag = NULL; -    xlator_t *this = NULL; -    dht_conf_t *conf = NULL; -    int ret = -1; - -    this = data; - -    conf = this->private; -    GF_VALIDATE_OR_GOTO(this->name, conf, exit); - -    defrag = conf->defrag; -    GF_VALIDATE_OR_GOTO(this->name, defrag, exit); - -    gf_defrag_pause_tier(this, defrag); - -    ret = 0; -exit: -    return ret; -} - -int -tier_reconfigure(xlator_t *this, dict_t *options) -{ -    dht_conf_t *conf = NULL; -    gf_defrag_info_t *defrag = NULL; -    char *mode = NULL; -    int migrate_mb = 0; -    gf_boolean_t req_pause = _gf_false; -    int ret = 0; -    call_frame_t *frame = NULL; -    gf_boolean_t last_compact_setting = _gf_false; - -    conf = this->private; - -    if (conf->defrag) { -        defrag = conf->defrag; -        GF_OPTION_RECONF("tier-max-promote-file-size", -                         defrag->tier_conf.tier_max_promote_size, options, -                         int32, out); - -        GF_OPTION_RECONF("tier-promote-frequency", -                         defrag->tier_conf.tier_promote_frequency, options, -                         int32, out); - -        GF_OPTION_RECONF("tier-demote-frequency", -                         defrag->tier_conf.tier_demote_frequency, options, -                         int32, out); - -        GF_OPTION_RECONF("write-freq-threshold", defrag->write_freq_threshold, -                         options, int32, out); - -        GF_OPTION_RECONF("read-freq-threshold", defrag->read_freq_threshold, -                         options, int32, out); - -        GF_OPTION_RECONF("watermark-hi", defrag->tier_conf.watermark_hi, -                         options, int32, out); - -        GF_OPTION_RECONF("watermark-low", defrag->tier_conf.watermark_low, -                         options, int32, out); - -        last_compact_setting = defrag->tier_conf.compact_active; - -        GF_OPTION_RECONF("tier-compact", defrag->tier_conf.compact_active, -                         options, bool, out); - -        if (last_compact_setting != defrag->tier_conf.compact_active) { -            defrag->tier_conf.compact_mode_switched_hot = _gf_true; -            defrag->tier_conf.compact_mode_switched_cold = _gf_true; -            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_TIER_STATUS, -                   "compact mode switched"); -        } - -        GF_OPTION_RECONF("tier-hot-compact-frequency", -                         defrag->tier_conf.tier_compact_hot_frequency, options, -                         int32, out); - -        GF_OPTION_RECONF("tier-cold-compact-frequency", -                         defrag->tier_conf.tier_compact_cold_frequency, options, -                         int32, out); - -        GF_OPTION_RECONF("tier-mode", mode, options, str, out); -        defrag->tier_conf.mode = tier_validate_mode(mode); - -        GF_OPTION_RECONF("tier-max-mb", migrate_mb, options, int32, out); -        defrag->tier_conf.max_migrate_bytes = (uint64_t)migrate_mb * 1024 * -                                              1024; - -        GF_OPTION_RECONF("tier-max-files", defrag->tier_conf.max_migrate_files, -                         options, int32, out); - -        GF_OPTION_RECONF("tier-query-limit", defrag->tier_conf.query_limit, -                         options, int32, out); - -        GF_OPTION_RECONF("tier-pause", req_pause, options, bool, out); - -        if (req_pause == _gf_true) { -            frame = create_frame(this, this->ctx->pool); -            if (!frame) -                goto out; - -            frame->root->pid = GF_CLIENT_PID_DEFRAG; - -            ret = synctask_new(this->ctx->env, tier_cli_pause, -                               tier_cli_pause_done, frame, this); - -            if (ret) { -                gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                       "pause tier failed on reconfigure"); -            } -        } else { -            ret = gf_defrag_resume_tier(this, defrag); -            if (ret) { -                gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, -                       "resume tier failed on reconfigure"); -            } -        } -    } - -out: -    return dht_reconfigure(this, options); -} - -void -tier_fini(xlator_t *this) -{ -    if (libhandle) -        dlclose(libhandle); - -    GF_FREE(demotion_qfile); -    GF_FREE(promotion_qfile); - -    dht_fini(this); -} - -class_methods_t class_methods = {.init = tier_init, -                                 .fini = tier_fini, -                                 .reconfigure = tier_reconfigure, -                                 .notify = dht_notify}; - -struct xlator_fops fops = { - -    .lookup = dht_lookup, -    .create = tier_create, -    .mknod = dht_mknod, - -    .open = dht_open, -    .statfs = tier_statfs, -    .opendir = dht_opendir, -    .readdir = tier_readdir, -    .readdirp = tier_readdirp, -    .fsyncdir = dht_fsyncdir, -    .symlink = dht_symlink, -    .unlink = tier_unlink, -    .link = tier_link, -    .mkdir = dht_mkdir, -    .rmdir = dht_rmdir, -    .rename = dht_rename, -    .entrylk = dht_entrylk, -    .fentrylk = dht_fentrylk, - -    /* Inode read operations */ -    .stat = dht_stat, -    .fstat = dht_fstat, -    .access = dht_access, -    .readlink = dht_readlink, -    .getxattr = dht_getxattr, -    .fgetxattr = dht_fgetxattr, -    .readv = dht_readv, -    .flush = dht_flush, -    .fsync = dht_fsync, -    .inodelk = dht_inodelk, -    .finodelk = dht_finodelk, -    .lk = dht_lk, - -    /* Inode write operations */ -    .fremovexattr = dht_fremovexattr, -    .removexattr = dht_removexattr, -    .setxattr = dht_setxattr, -    .fsetxattr = dht_fsetxattr, -    .truncate = dht_truncate, -    .ftruncate = dht_ftruncate, -    .writev = dht_writev, -    .xattrop = dht_xattrop, -    .fxattrop = dht_fxattrop, -    .setattr = dht_setattr, -    .fsetattr = dht_fsetattr, -    .fallocate = dht_fallocate, -    .discard = dht_discard, -    .zerofill = dht_zerofill, -}; - -struct xlator_cbks cbks = {.release = dht_release, .forget = dht_forget}; diff --git a/xlators/cluster/dht/src/tier.h b/xlators/cluster/dht/src/tier.h deleted file mode 100644 index a20b1db07e0..00000000000 --- a/xlators/cluster/dht/src/tier.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -  Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _TIER_H_ -#define _TIER_H_ - -/******************************************************************************/ -/* This is from dht-rebalancer.c as we don't have dht-rebalancer.h */ -#include "dht-common.h" -#include <glusterfs/xlator.h> -#include <signal.h> -#include <fnmatch.h> -#include <signal.h> - -/* - * Size of timer wheel. We would not promote or demote less - * frequently than this number. - */ -#define TIMER_SECS 3600 - -#include "gfdb_data_store.h" -#include <ctype.h> -#include <sys/stat.h> - -#define PROMOTION_QFILE "promotequeryfile" -#define DEMOTION_QFILE "demotequeryfile" - -#define TIER_HASHED_SUBVOL conf->subvolumes[0] -#define TIER_UNHASHED_SUBVOL conf->subvolumes[1] - -#define GET_QFILE_PATH(is_promotion)                                           \ -    (is_promotion) ? promotion_qfile : demotion_qfile - -typedef struct tier_qfile_array { -    int *fd_array; -    ssize_t array_size; -    ssize_t next_index; -    /* Indicate the number of exhuasted FDs*/ -    ssize_t exhausted_count; -} tier_qfile_array_t; - -typedef struct _query_cbk_args { -    xlator_t *this; -    gf_defrag_info_t *defrag; -    /* This is write */ -    int query_fd; -    int is_promotion; -    int is_compaction; -    /* This is for read */ -    tier_qfile_array_t *qfile_array; -} query_cbk_args_t; - -int -gf_run_tier(xlator_t *this, gf_defrag_info_t *defrag); - -typedef struct gfdb_brick_info { -    gfdb_time_t *time_stamp; -    gf_boolean_t _gfdb_promote; -    query_cbk_args_t *_query_cbk_args; -} gfdb_brick_info_t; - -typedef struct brick_list { -    xlator_t *xlator; -    char *brick_db_path; -    char brick_name[NAME_MAX]; -    char qfile_path[PATH_MAX]; -    struct list_head list; -} tier_brick_list_t; - -typedef struct _dm_thread_args { -    xlator_t *this; -    gf_defrag_info_t *defrag; -    struct list_head *brick_list; -    int freq_time; -    int return_value; -    int is_promotion; -    int is_compaction; -    gf_boolean_t is_hot_tier; -} migration_args_t; - -typedef enum tier_watermark_op_ { -    TIER_WM_NONE = 0, -    TIER_WM_LOW, -    TIER_WM_HI, -    TIER_WM_MID -} tier_watermark_op_t; - -#define DEFAULT_PROMOTE_FREQ_SEC 120 -#define DEFAULT_DEMOTE_FREQ_SEC 120 -#define DEFAULT_HOT_COMPACT_FREQ_SEC 604800 -#define DEFAULT_COLD_COMPACT_FREQ_SEC 604800 -#define DEFAULT_DEMOTE_DEGRADED 1 -#define DEFAULT_WRITE_FREQ_SEC 0 -#define DEFAULT_READ_FREQ_SEC 0 -#define DEFAULT_WM_LOW 75 -#define DEFAULT_WM_HI 90 -#define DEFAULT_TIER_MODE TIER_MODE_TEST -#define DEFAULT_COMP_MODE _gf_true -#define DEFAULT_TIER_MAX_MIGRATE_MB 1000 -#define DEFAULT_TIER_MAX_MIGRATE_FILES 5000 -#define DEFAULT_TIER_QUERY_LIMIT 100 - -#endif diff --git a/xlators/cluster/dht/src/tier.sym b/xlators/cluster/dht/src/tier.sym deleted file mode 100644 index 60205d145b6..00000000000 --- a/xlators/cluster/dht/src/tier.sym +++ /dev/null @@ -1,9 +0,0 @@ -fops -cbks -class_methods -dht_methods -tier_methods -options -mem_acct_init -reconfigure -dumpops diff --git a/xlators/cluster/stripe/src/Makefile.am b/xlators/cluster/stripe/src/Makefile.am deleted file mode 100644 index 2b594567db1..00000000000 --- a/xlators/cluster/stripe/src/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -xlator_LTLIBRARIES = stripe.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster - -stripe_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) - - -stripe_la_SOURCES = stripe.c stripe-helpers.c \ -	$(top_builddir)/xlators/lib/src/libxlator.c - -stripe_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -noinst_HEADERS = stripe.h stripe-mem-types.h \ -	$(top_builddir)/xlators/lib/src/libxlator.h - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/xlators/lib/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -CLEANFILES =  - diff --git a/xlators/cluster/stripe/src/stripe-helpers.c b/xlators/cluster/stripe/src/stripe-helpers.c deleted file mode 100644 index 35342378985..00000000000 --- a/xlators/cluster/stripe/src/stripe-helpers.c +++ /dev/null @@ -1,658 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <fnmatch.h> - -#include "stripe.h" -#include <glusterfs/byte-order.h> -#include <glusterfs/mem-types.h> -#include <glusterfs/logging.h> - -void -stripe_local_wipe(stripe_local_t *local) -{ -    if (!local) -        goto out; - -    loc_wipe(&local->loc); -    loc_wipe(&local->loc2); - -    if (local->fd) -        fd_unref(local->fd); - -    if (local->inode) -        inode_unref(local->inode); - -    if (local->xattr) -        dict_unref(local->xattr); - -    if (local->xdata) -        dict_unref(local->xdata); - -out: -    return; -} - -int -stripe_aggregate(dict_t *this, char *key, data_t *value, void *data) -{ -    dict_t *dst = NULL; -    int64_t *ptr = 0, *size = NULL; -    int32_t ret = -1; - -    dst = data; - -    if (strcmp(key, QUOTA_SIZE_KEY) == 0) { -        ret = dict_get_bin(dst, key, (void **)&size); -        if (ret < 0) { -            size = GF_CALLOC(1, sizeof(int64_t), gf_common_mt_char); -            if (size == NULL) { -                gf_log("stripe", GF_LOG_WARNING, "memory allocation failed"); -                goto out; -            } -            ret = dict_set_bin(dst, key, size, sizeof(int64_t)); -            if (ret < 0) { -                gf_log("stripe", GF_LOG_WARNING, -                       "stripe aggregate dict set failed"); -                GF_FREE(size); -                goto out; -            } -        } - -        ptr = data_to_bin(value); -        if (ptr == NULL) { -            gf_log("stripe", GF_LOG_WARNING, "data to bin failed"); -            goto out; -        } - -        *size = hton64(ntoh64(*size) + ntoh64(*ptr)); -    } else if (strcmp(key, GF_CONTENT_KEY)) { -        /* No need to aggregate 'CONTENT' data */ -        ret = dict_set(dst, key, value); -        if (ret) -            gf_log("stripe", GF_LOG_WARNING, "xattr dict set failed"); -    } - -out: -    return 0; -} - -void -stripe_aggregate_xattr(dict_t *dst, dict_t *src) -{ -    if ((dst == NULL) || (src == NULL)) { -        goto out; -    } - -    dict_foreach(src, stripe_aggregate, dst); -out: -    return; -} - -int32_t -stripe_xattr_aggregate(char *buffer, stripe_local_t *local, int32_t *total) -{ -    int32_t i = 0; -    int32_t ret = -1; -    int32_t len = 0; -    char *sbuf = NULL; -    stripe_xattr_sort_t *xattr = NULL; - -    if (!buffer || !local || !local->xattr_list) -        goto out; - -    sbuf = buffer; - -    for (i = 0; i < local->nallocs; i++) { -        xattr = local->xattr_list + i; -        len = xattr->xattr_len - 1; /* length includes \0 */ - -        if (len && xattr && xattr->xattr_value) { -            memcpy(buffer, xattr->xattr_value, len); -            buffer += len; -            *buffer++ = ' '; -        } -    } - -    *--buffer = '\0'; -    if (total) -        *total = buffer - sbuf; -    ret = 0; - -out: -    return ret; -} - -int32_t -stripe_free_xattr_str(stripe_local_t *local) -{ -    int32_t i = 0; -    int32_t ret = -1; -    stripe_xattr_sort_t *xattr = NULL; - -    if (!local || !local->xattr_list) -        goto out; - -    for (i = 0; i < local->nallocs; i++) { -        xattr = local->xattr_list + i; - -        if (xattr && xattr->xattr_value) -            GF_FREE(xattr->xattr_value); -    } - -    ret = 0; -out: -    return ret; -} - -int32_t -stripe_fill_lockinfo_xattr(xlator_t *this, stripe_local_t *local, -                           void **xattr_serz) -{ -    int32_t ret = -1, i = 0, len = 0; -    dict_t *tmp1 = NULL, *tmp2 = NULL; -    char *buf = NULL; -    stripe_xattr_sort_t *xattr = NULL; - -    if (xattr_serz == NULL) { -        goto out; -    } - -    tmp2 = dict_new(); - -    if (tmp2 == NULL) { -        goto out; -    } - -    for (i = 0; i < local->nallocs; i++) { -        xattr = local->xattr_list + i; -        len = xattr->xattr_len; - -        if (len && xattr && xattr->xattr_value) { -            ret = dict_reset(tmp2); -            if (ret < 0) { -                gf_log(this->name, GF_LOG_DEBUG, "dict_reset failed (%s)", -                       strerror(-ret)); -            } - -            ret = dict_unserialize(xattr->xattr_value, xattr->xattr_len, &tmp2); -            if (ret < 0) { -                gf_log(this->name, GF_LOG_WARNING, -                       "dict_unserialize failed (%s)", strerror(-ret)); -                ret = -1; -                goto out; -            } - -            tmp1 = dict_copy(tmp2, tmp1); -            if (tmp1 == NULL) { -                gf_log(this->name, GF_LOG_WARNING, "dict_copy failed (%s)", -                       strerror(-ret)); -                ret = -1; -                goto out; -            } -        } -    } - -    len = dict_serialized_length(tmp1); -    if (len > 0) { -        buf = GF_CALLOC(1, len, gf_common_mt_dict_t); -        if (buf == NULL) { -            ret = -1; -            goto out; -        } - -        ret = dict_serialize(tmp1, buf); -        if (ret < 0) { -            gf_log(this->name, GF_LOG_WARNING, "dict_serialize failed (%s)", -                   strerror(-ret)); -            GF_FREE(buf); -            ret = -1; -            goto out; -        } - -        *xattr_serz = buf; -    } - -    ret = 0; -out: -    if (tmp1 != NULL) { -        dict_unref(tmp1); -    } - -    if (tmp2 != NULL) { -        dict_unref(tmp2); -    } - -    return ret; -} - -int32_t -stripe_fill_pathinfo_xattr(xlator_t *this, stripe_local_t *local, -                           char **xattr_serz) -{ -    int ret = -1; -    int32_t padding = 0; -    int32_t tlen = 0; -    int len = 0; -    char stripe_size_str[20] = { -        0, -    }; -    char *pathinfo_serz = NULL; - -    if (!local) { -        gf_log(this->name, GF_LOG_ERROR, "Possible NULL deref"); -        goto out; -    } - -    len = snprintf(stripe_size_str, sizeof(stripe_size_str), "%" PRId64, -                   local->fctx ? local->fctx->stripe_size : 0); -    if (len < 0 || len >= sizeof(stripe_size_str)) -        goto out; -    /* extra bytes for decorations (brackets and <>'s) */ -    padding = strlen(this->name) + SLEN(STRIPE_PATHINFO_HEADER) + len + 7; -    local->xattr_total_len += (padding + 2); - -    pathinfo_serz = GF_MALLOC(local->xattr_total_len, gf_common_mt_char); -    if (!pathinfo_serz) -        goto out; - -    /* xlator info */ -    (void)sprintf(pathinfo_serz, "(<" STRIPE_PATHINFO_HEADER "%s:[%s]> ", -                  this->name, stripe_size_str); - -    ret = stripe_xattr_aggregate(pathinfo_serz + padding, local, &tlen); -    if (ret) { -        gf_log(this->name, GF_LOG_ERROR, "Cannot aggregate pathinfo list"); -        GF_FREE(pathinfo_serz); -        goto out; -    } - -    *(pathinfo_serz + padding + tlen) = ')'; -    *(pathinfo_serz + padding + tlen + 1) = '\0'; - -    *xattr_serz = pathinfo_serz; - -    ret = 0; -out: -    return ret; -} - -/** - * stripe_get_matching_bs - Get the matching block size for the given path. - */ -int32_t -stripe_get_matching_bs(const char *path, stripe_private_t *priv) -{ -    struct stripe_options *trav = NULL; -    uint64_t block_size = 0; - -    GF_VALIDATE_OR_GOTO("stripe", priv, out); -    GF_VALIDATE_OR_GOTO("stripe", path, out); - -    LOCK(&priv->lock); -    { -        block_size = priv->block_size; -        trav = priv->pattern; -        while (trav) { -            if (!fnmatch(trav->path_pattern, path, FNM_NOESCAPE)) { -                block_size = trav->block_size; -                break; -            } -            trav = trav->next; -        } -    } -    UNLOCK(&priv->lock); - -out: -    return block_size; -} - -int32_t -stripe_ctx_handle(xlator_t *this, call_frame_t *prev, stripe_local_t *local, -                  dict_t *dict) -{ -    char key[256] = { -        0, -    }; -    data_t *data = NULL; -    int32_t index = 0; -    stripe_private_t *priv = NULL; - -    priv = this->private; - -    if (!local->fctx) { -        local->fctx = GF_CALLOC(1, sizeof(stripe_fd_ctx_t), -                                gf_stripe_mt_stripe_fd_ctx_t); -        if (!local->fctx) { -            local->op_errno = ENOMEM; -            local->op_ret = -1; -            goto out; -        } - -        local->fctx->static_array = 0; -    } -    /* Stripe block size */ -    sprintf(key, "trusted.%s.stripe-size", this->name); -    data = dict_get(dict, key); -    if (!data) { -        local->xattr_self_heal_needed = 1; -        gf_log(this->name, GF_LOG_ERROR, "Failed to get stripe-size"); -        goto out; -    } else { -        if (!local->fctx->stripe_size) { -            local->fctx->stripe_size = data_to_int64(data); -        } - -        if (local->fctx->stripe_size != data_to_int64(data)) { -            gf_log(this->name, GF_LOG_WARNING, -                   "stripe-size mismatch in blocks"); -            local->xattr_self_heal_needed = 1; -        } -    } - -    /* Stripe count */ -    sprintf(key, "trusted.%s.stripe-count", this->name); -    data = dict_get(dict, key); - -    if (!data) { -        local->xattr_self_heal_needed = 1; -        gf_log(this->name, GF_LOG_ERROR, "Failed to get stripe-count"); -        goto out; -    } -    if (!local->fctx->xl_array) { -        local->fctx->stripe_count = data_to_int32(data); -        if (!local->fctx->stripe_count) { -            gf_log(this->name, GF_LOG_ERROR, "error with stripe-count xattr"); -            local->op_ret = -1; -            local->op_errno = EIO; -            goto out; -        } - -        local->fctx->xl_array = GF_CALLOC(local->fctx->stripe_count, -                                          sizeof(xlator_t *), -                                          gf_stripe_mt_xlator_t); - -        if (!local->fctx->xl_array) { -            local->op_errno = ENOMEM; -            local->op_ret = -1; -            goto out; -        } -    } -    if (local->fctx->stripe_count != data_to_int32(data)) { -        gf_log(this->name, GF_LOG_ERROR, -               "error with stripe-count xattr (%d != %d)", -               local->fctx->stripe_count, data_to_int32(data)); -        local->op_ret = -1; -        local->op_errno = EIO; -        goto out; -    } - -    /* index */ -    sprintf(key, "trusted.%s.stripe-index", this->name); -    data = dict_get(dict, key); -    if (!data) { -        local->xattr_self_heal_needed = 1; -        gf_log(this->name, GF_LOG_ERROR, "Failed to get stripe-index"); -        goto out; -    } -    index = data_to_int32(data); -    if (index > priv->child_count) { -        gf_log(this->name, GF_LOG_ERROR, "error with stripe-index xattr (%d)", -               index); -        local->op_ret = -1; -        local->op_errno = EIO; -        goto out; -    } -    if (local->fctx->xl_array) { -        if (!local->fctx->xl_array[index]) -            local->fctx->xl_array[index] = prev->this; -    } - -    sprintf(key, "trusted.%s.stripe-coalesce", this->name); -    data = dict_get(dict, key); -    if (!data) { -        /* -         * The file was probably created prior to coalesce support. -         * Assume non-coalesce mode for this file to maintain backwards -         * compatibility. -         */ -        gf_log(this->name, GF_LOG_DEBUG, -               "missing stripe-coalesce " -               "attr, assume non-coalesce mode"); -        local->fctx->stripe_coalesce = 0; -    } else { -        local->fctx->stripe_coalesce = data_to_int32(data); -    } - -out: -    return 0; -} - -int32_t -stripe_xattr_request_build(xlator_t *this, dict_t *dict, uint64_t stripe_size, -                           uint32_t stripe_count, uint32_t stripe_index, -                           uint32_t stripe_coalesce) -{ -    char key[256] = { -        0, -    }; -    int32_t ret = -1; - -    sprintf(key, "trusted.%s.stripe-size", this->name); -    ret = dict_set_int64(dict, key, stripe_size); -    if (ret) { -        gf_log(this->name, GF_LOG_WARNING, "failed to set %s in xattr_req dict", -               key); -        goto out; -    } - -    sprintf(key, "trusted.%s.stripe-count", this->name); -    ret = dict_set_int32(dict, key, stripe_count); -    if (ret) { -        gf_log(this->name, GF_LOG_WARNING, "failed to set %s in xattr_req dict", -               key); -        goto out; -    } - -    sprintf(key, "trusted.%s.stripe-index", this->name); -    ret = dict_set_int32(dict, key, stripe_index); -    if (ret) { -        gf_log(this->name, GF_LOG_WARNING, "failed to set %s in xattr_req dict", -               key); -        goto out; -    } - -    sprintf(key, "trusted.%s.stripe-coalesce", this->name); -    ret = dict_set_int32(dict, key, stripe_coalesce); -    if (ret) { -        gf_log(this->name, GF_LOG_WARNING, "failed to set %s in xattr_req_dict", -               key); -        goto out; -    } -out: -    return ret; -} - -static int -set_default_block_size(stripe_private_t *priv, char *num) -{ -    int ret = -1; -    GF_VALIDATE_OR_GOTO("stripe", THIS, out); -    GF_VALIDATE_OR_GOTO(THIS->name, priv, out); -    GF_VALIDATE_OR_GOTO(THIS->name, num, out); - -    if (gf_string2bytesize_uint64(num, &priv->block_size) != 0) { -        gf_log(THIS->name, GF_LOG_ERROR, "invalid number format \"%s\"", num); -        goto out; -    } - -    ret = 0; - -out: -    return ret; -} - -int -set_stripe_block_size(xlator_t *this, stripe_private_t *priv, char *data) -{ -    int ret = -1; -    char *tmp_str = NULL; -    char *tmp_str1 = NULL; -    char *dup_str = NULL; -    char *stripe_str = NULL; -    char *pattern = NULL; -    char *num = NULL; -    struct stripe_options *temp_stripeopt = NULL; -    struct stripe_options *stripe_opt = NULL; - -    if (!this || !priv || !data) -        goto out; - -    /* Get the pattern for striping. -       "option block-size *avi:10MB" etc */ -    stripe_str = strtok_r(data, ",", &tmp_str); -    while (stripe_str) { -        dup_str = gf_strdup(stripe_str); -        stripe_opt = GF_CALLOC(1, sizeof(struct stripe_options), -                               gf_stripe_mt_stripe_options); -        if (!stripe_opt) { -            goto out; -        } - -        pattern = strtok_r(dup_str, ":", &tmp_str1); -        num = strtok_r(NULL, ":", &tmp_str1); -        if (!num) { -            num = pattern; -            pattern = "*"; -            ret = set_default_block_size(priv, num); -            if (ret) -                goto out; -        } -        if (gf_string2bytesize_uint64(num, &stripe_opt->block_size) != 0) { -            gf_log(this->name, GF_LOG_ERROR, "invalid number format \"%s\"", -                   num); -            goto out; -        } - -        if (stripe_opt->block_size < STRIPE_MIN_BLOCK_SIZE) { -            gf_log(this->name, GF_LOG_ERROR, -                   "Invalid Block-size: " -                   "%s. Should be at least %llu bytes", -                   num, STRIPE_MIN_BLOCK_SIZE); -            goto out; -        } -        if (stripe_opt->block_size % 512) { -            gf_log(this->name, GF_LOG_ERROR, -                   "Block-size: %s should" -                   " be a multiple of 512 bytes", -                   num); -            goto out; -        } - -        memcpy(stripe_opt->path_pattern, pattern, strlen(pattern)); - -        gf_log(this->name, GF_LOG_DEBUG, -               "block-size : pattern %s : size %" PRId64, -               stripe_opt->path_pattern, stripe_opt->block_size); - -        if (priv->pattern) -            temp_stripeopt = NULL; -        else -            temp_stripeopt = priv->pattern; - -        stripe_opt->next = temp_stripeopt; - -        priv->pattern = stripe_opt; -        stripe_opt = NULL; - -        GF_FREE(dup_str); -        dup_str = NULL; - -        stripe_str = strtok_r(NULL, ",", &tmp_str); -    } - -    ret = 0; -out: - -    GF_FREE(dup_str); - -    GF_FREE(stripe_opt); - -    return ret; -} - -int32_t -stripe_iatt_merge(struct iatt *from, struct iatt *to) -{ -    if (to->ia_size < from->ia_size) -        to->ia_size = from->ia_size; -    if (to->ia_mtime < from->ia_mtime) -        to->ia_mtime = from->ia_mtime; -    if (to->ia_ctime < from->ia_ctime) -        to->ia_ctime = from->ia_ctime; -    if (to->ia_atime < from->ia_atime) -        to->ia_atime = from->ia_atime; -    return 0; -} - -off_t -coalesced_offset(off_t offset, uint64_t stripe_size, int stripe_count) -{ -    size_t line_size = 0; -    uint64_t stripe_num = 0; -    off_t coalesced_offset = 0; - -    line_size = stripe_size * stripe_count; -    stripe_num = offset / line_size; - -    coalesced_offset = (stripe_num * stripe_size) + (offset % stripe_size); - -    return coalesced_offset; -} - -off_t -uncoalesced_size(off_t size, uint64_t stripe_size, int stripe_count, -                 int stripe_index) -{ -    uint64_t nr_full_stripe_chunks = 0, mod = 0; - -    if (!size) -        return size; - -    /* -     * Estimate the number of fully written stripes from the -     * local file size. Each stripe_size chunk corresponds to -     * a stripe. -     */ -    nr_full_stripe_chunks = (size / stripe_size) * stripe_count; -    mod = size % stripe_size; - -    if (!mod) { -        /* -         * There is no remainder, thus we could have overestimated -         * the size of the file in terms of chunks. Trim the number -         * of chunks by the following stripe members and leave it -         * up to those nodes to respond with a larger size (if -         * necessary). -         */ -        nr_full_stripe_chunks -= stripe_count - (stripe_index + 1); -        size = nr_full_stripe_chunks * stripe_size; -    } else { -        /* -         * There is a remainder and thus we own the last chunk of the -         * file. Add the preceding stripe members of the final stripe -         * along with the remainder to calculate the exact size. -         */ -        nr_full_stripe_chunks += stripe_index; -        size = nr_full_stripe_chunks * stripe_size + mod; -    } - -    return size; -} diff --git a/xlators/cluster/stripe/src/stripe-mem-types.h b/xlators/cluster/stripe/src/stripe-mem-types.h deleted file mode 100644 index 3ca6ecc7a41..00000000000 --- a/xlators/cluster/stripe/src/stripe-mem-types.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __STRIPE_MEM_TYPES_H__ -#define __STRIPE_MEM_TYPES_H__ - -#include <glusterfs/mem-types.h> - -enum gf_stripe_mem_types_ { -    gf_stripe_mt_iovec = gf_common_mt_end + 1, -    gf_stripe_mt_stripe_replies, -    gf_stripe_mt_stripe_fd_ctx_t, -    gf_stripe_mt_char, -    gf_stripe_mt_int8_t, -    gf_stripe_mt_int32_t, -    gf_stripe_mt_xlator_t, -    gf_stripe_mt_stripe_private_t, -    gf_stripe_mt_stripe_options, -    gf_stripe_mt_xattr_sort_t, -    gf_stripe_mt_end -}; -#endif diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c deleted file mode 100644 index 557a8185352..00000000000 --- a/xlators/cluster/stripe/src/stripe.c +++ /dev/null @@ -1,5612 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -/** - * xlators/cluster/stripe: - *    Stripe translator, stripes the data across its child nodes, - *    as per the options given in the volfile. The striping works - *    fairly simple. It writes files at different offset as per - *    calculation. So, 'ls -l' output at the real posix level will - *    show file size bigger than the actual size. But when one does - *    'df' or 'du <file>', real size of the file on the server is shown. - * - * WARNING: - *  Stripe translator can't regenerate data if a child node gets disconnected. - *  So, no 'self-heal' for stripe. Hence the advice, use stripe only when its - *  very much necessary, or else, use it in combination with AFR, to have a - *  backup copy. - */ -#include <fnmatch.h> -#include "stripe.h" -#include "libxlator.h" -#include <glusterfs/byte-order.h> -#include <glusterfs/statedump.h> - -struct volume_options options[]; - -int32_t -stripe_sh_chown_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, struct iatt *preop, -                    struct iatt *postop, dict_t *xdata) -{ -    int callcnt = -1; -    stripe_local_t *local = NULL; - -    if (!this || !frame || !frame->local) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        STRIPE_STACK_DESTROY(frame); -    } -out: -    return 0; -} - -int32_t -stripe_sh_make_entry_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, inode_t *inode, -                         struct iatt *buf, struct iatt *preparent, -                         struct iatt *postparent, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!frame || !frame->local || !cookie || !this) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    STACK_WIND(frame, stripe_sh_chown_cbk, prev->this, -               prev->this->fops->setattr, &local->loc, &local->stbuf, -               (GF_SET_ATTR_UID | GF_SET_ATTR_GID), NULL); - -out: -    return 0; -} - -int32_t -stripe_entry_self_heal(call_frame_t *frame, xlator_t *this, -                       stripe_local_t *local) -{ -    xlator_list_t *trav = NULL; -    call_frame_t *rframe = NULL; -    stripe_local_t *rlocal = NULL; -    stripe_private_t *priv = NULL; -    dict_t *xdata = NULL; -    int ret = 0; - -    if (!local || !this || !frame) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    if (!(IA_ISREG(local->stbuf.ia_type) || IA_ISDIR(local->stbuf.ia_type))) -        return 0; - -    priv = this->private; -    trav = this->children; -    rframe = copy_frame(frame); -    if (!rframe) { -        goto out; -    } -    rlocal = mem_get0(this->local_pool); -    if (!rlocal) { -        goto out; -    } -    rframe->local = rlocal; -    rlocal->call_count = priv->child_count; -    loc_copy(&rlocal->loc, &local->loc); -    memcpy(&rlocal->stbuf, &local->stbuf, sizeof(struct iatt)); - -    xdata = dict_new(); -    if (!xdata) -        goto out; - -    ret = dict_set_gfuuid(xdata, "gfid-req", local->stbuf.ia_gfid, true); -    if (ret) -        gf_log(this->name, GF_LOG_WARNING, "%s: failed to set gfid-req", -               local->loc.path); - -    while (trav) { -        if (IA_ISREG(local->stbuf.ia_type)) { -            STACK_WIND( -                rframe, stripe_sh_make_entry_cbk, trav->xlator, -                trav->xlator->fops->mknod, &local->loc, -                st_mode_from_ia(local->stbuf.ia_prot, local->stbuf.ia_type), 0, -                0, xdata); -        } -        if (IA_ISDIR(local->stbuf.ia_type)) { -            STACK_WIND( -                rframe, stripe_sh_make_entry_cbk, trav->xlator, -                trav->xlator->fops->mkdir, &local->loc, -                st_mode_from_ia(local->stbuf.ia_prot, local->stbuf.ia_type), 0, -                xdata); -        } -        trav = trav->next; -    } - -    if (xdata) -        dict_unref(xdata); -    return 0; - -out: -    if (rframe) -        STRIPE_STACK_DESTROY(rframe); - -    return 0; -} - -int32_t -stripe_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, inode_t *inode, -                  struct iatt *buf, dict_t *xdata, struct iatt *postparent) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; -    int ret = 0; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            if ((op_errno != ENOENT) && (op_errno != ESTALE)) -                gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                       prev->this->name, strerror(op_errno)); -            if (local->op_errno != ESTALE) -                local->op_errno = op_errno; -            if (((op_errno != ENOENT) && (op_errno != ENOTCONN) && -                 (op_errno != ESTALE)) || -                (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -            if (op_errno == ENOENT) -                local->entry_self_heal_needed = 1; -        } - -        if (op_ret >= 0) { -            local->op_ret = 0; -            if (IA_ISREG(buf->ia_type)) { -                ret = stripe_ctx_handle(this, prev, local, xdata); -                if (ret) -                    gf_log(this->name, GF_LOG_ERROR, -                           "Error getting fctx info from" -                           " dict"); -            } - -            if (FIRST_CHILD(this) == prev->this) { -                local->stbuf = *buf; -                local->postparent = *postparent; -                local->inode = inode_ref(inode); -                if (xdata) -                    local->xdata = dict_ref(xdata); -                if (local->xattr) { -                    stripe_aggregate_xattr(local->xdata, local->xattr); -                    dict_unref(local->xattr); -                    local->xattr = NULL; -                } -            } - -            if (!local->xdata && !local->xattr) { -                local->xattr = dict_ref(xdata); -            } else if (local->xdata) { -                stripe_aggregate_xattr(local->xdata, xdata); -            } else if (local->xattr) { -                stripe_aggregate_xattr(local->xattr, xdata); -            } - -            local->stbuf_blocks += buf->ia_blocks; -            local->postparent_blocks += postparent->ia_blocks; - -            correct_file_size(buf, local->fctx, prev); - -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -            if (local->postparent_size < postparent->ia_size) -                local->postparent_size = postparent->ia_size; - -            if (gf_uuid_is_null(local->ia_gfid)) -                gf_uuid_copy(local->ia_gfid, buf->ia_gfid); - -            /* Make sure the gfid on all the nodes are same */ -            if (gf_uuid_compare(local->ia_gfid, buf->ia_gfid)) { -                gf_log(this->name, GF_LOG_WARNING, -                       "%s: gfid different on subvolume %s", local->loc.path, -                       prev->this->name); -            } -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->op_ret == 0 && local->entry_self_heal_needed && -            !gf_uuid_is_null(local->loc.inode->gfid)) -            stripe_entry_self_heal(frame, this, local); - -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret != -1) { -            local->stbuf.ia_blocks = local->stbuf_blocks; -            local->stbuf.ia_size = local->stbuf_size; -            local->postparent.ia_blocks = local->postparent_blocks; -            local->postparent.ia_size = local->postparent_size; -            inode_ctx_put(local->inode, this, (uint64_t)(long)local->fctx); -        } - -        STRIPE_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, -                            local->inode, &local->stbuf, local->xdata, -                            &local->postparent); -    } -out: -    return 0; -} - -int32_t -stripe_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    xlator_list_t *trav = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = EINVAL; -    int64_t filesize = 0; -    int ret = 0; -    uint64_t tmpctx = 0; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    loc_copy(&local->loc, loc); - -    inode_ctx_get(local->inode, this, &tmpctx); -    if (tmpctx) -        local->fctx = (stripe_fd_ctx_t *)(long)tmpctx; - -    /* quick-read friendly changes */ -    if (xdata && dict_get(xdata, GF_CONTENT_KEY)) { -        ret = dict_get_int64(xdata, GF_CONTENT_KEY, &filesize); -        if (!ret && (filesize > priv->block_size)) -            dict_del(xdata, GF_CONTENT_KEY); -    } - -    /* get stripe-size xattr on lookup. This would be required for -     * open/read/write/pathinfo calls. Hence we send down the request -     * even when type == IA_INVAL */ - -    /* -     * We aren't guaranteed to have xdata here. We need the format info for -     * the file, so allocate xdata if necessary. -     */ -    if (!xdata) -        xdata = dict_new(); -    else -        xdata = dict_ref(xdata); - -    if (xdata && -        (IA_ISREG(loc->inode->ia_type) || (loc->inode->ia_type == IA_INVAL))) { -        ret = stripe_xattr_request_build(this, xdata, 8, 4, 4, 0); -        if (ret) -            gf_log(this->name, GF_LOG_ERROR, -                   "Failed to build" -                   " xattr request for %s", -                   loc->path); -    } - -    /* Every time in stripe lookup, all child nodes -       should be looked up */ -    local->call_count = priv->child_count; -    while (trav) { -        STACK_WIND(frame, stripe_lookup_cbk, trav->xlator, -                   trav->xlator->fops->lookup, loc, xdata); -        trav = trav->next; -    } - -    dict_unref(xdata); - -    return 0; -err: -    STRIPE_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, struct iatt *buf, -                dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } - -        if (op_ret == 0) { -            local->op_ret = 0; - -            if (FIRST_CHILD(this) == prev->this) { -                local->stbuf = *buf; -            } - -            local->stbuf_blocks += buf->ia_blocks; - -            correct_file_size(buf, local->fctx, prev); - -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret != -1) { -            local->stbuf.ia_size = local->stbuf_size; -            local->stbuf.ia_blocks = local->stbuf_blocks; -        } - -        STRIPE_STACK_UNWIND(stat, frame, local->op_ret, local->op_errno, -                            &local->stbuf, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    xlator_list_t *trav = NULL; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    if (IA_ISREG(loc->inode->ia_type)) { -        inode_ctx_get(loc->inode, this, (uint64_t *)&fctx); -        if (!fctx) -            goto err; -        local->fctx = fctx; -    } - -    while (trav) { -        STACK_WIND(frame, stripe_stat_cbk, trav->xlator, -                   trav->xlator->fops->stat, loc, NULL); -        trav = trav->next; -    } - -    return 0; - -err: -    STRIPE_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL); -    return 0; -} - -int32_t -stripe_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, struct statvfs *stbuf, -                  dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    int32_t callcnt = 0; - -    if (!this || !frame || !frame->local) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret && (op_errno != ENOTCONN)) { -            local->op_errno = op_errno; -        } -        if (op_ret == 0) { -            struct statvfs *dict_buf = &local->statvfs_buf; -            dict_buf->f_bsize = stbuf->f_bsize; -            dict_buf->f_frsize = stbuf->f_frsize; -            dict_buf->f_blocks += stbuf->f_blocks; -            dict_buf->f_bfree += stbuf->f_bfree; -            dict_buf->f_bavail += stbuf->f_bavail; -            dict_buf->f_files += stbuf->f_files; -            dict_buf->f_ffree += stbuf->f_ffree; -            dict_buf->f_favail += stbuf->f_favail; -            dict_buf->f_fsid = stbuf->f_fsid; -            dict_buf->f_flag = stbuf->f_flag; -            dict_buf->f_namemax = stbuf->f_namemax; -            local->op_ret = 0; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        STRIPE_STACK_UNWIND(statfs, frame, local->op_ret, local->op_errno, -                            &local->statvfs_buf, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    xlator_list_t *trav = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); - -    trav = this->children; -    priv = this->private; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    local->op_errno = ENOTCONN; -    frame->local = local; - -    local->call_count = priv->child_count; -    while (trav) { -        STACK_WIND(frame, stripe_statfs_cbk, trav->xlator, -                   trav->xlator->fops->statfs, loc, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); -    return 0; -} - -int32_t -stripe_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                    struct iatt *postbuf, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } - -        if (op_ret == 0) { -            local->op_ret = 0; -            if (FIRST_CHILD(this) == prev->this) { -                local->pre_buf = *prebuf; -                local->post_buf = *postbuf; -            } - -            local->prebuf_blocks += prebuf->ia_blocks; -            local->postbuf_blocks += postbuf->ia_blocks; - -            correct_file_size(prebuf, local->fctx, prev); -            correct_file_size(postbuf, local->fctx, prev); - -            if (local->prebuf_size < prebuf->ia_size) -                local->prebuf_size = prebuf->ia_size; - -            if (local->postbuf_size < postbuf->ia_size) -                local->postbuf_size = postbuf->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret != -1) { -            local->pre_buf.ia_blocks = local->prebuf_blocks; -            local->pre_buf.ia_size = local->prebuf_size; -            local->post_buf.ia_blocks = local->postbuf_blocks; -            local->post_buf.ia_size = local->postbuf_size; -        } - -        STRIPE_STACK_UNWIND(truncate, frame, local->op_ret, local->op_errno, -                            &local->pre_buf, &local->post_buf, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, -                dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = EINVAL; -    int i, eof_idx; -    off_t dest_offset, tmp_offset; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    inode_ctx_get(loc->inode, this, (uint64_t *)&fctx); -    if (!fctx) { -        gf_log(this->name, GF_LOG_ERROR, "no stripe context"); -        op_errno = EINVAL; -        goto err; -    } - -    local->fctx = fctx; -    eof_idx = (offset / fctx->stripe_size) % fctx->stripe_count; - -    for (i = 0; i < fctx->stripe_count; i++) { -        if (!fctx->xl_array[i]) { -            gf_log(this->name, GF_LOG_ERROR, "no xlator at index %d", i); -            op_errno = EINVAL; -            goto err; -        } - -        if (fctx->stripe_coalesce) { -            /* -             * The node that owns EOF is truncated to the exact -             * coalesced offset. Nodes prior to this index should -             * be rounded up to the size of the complete stripe, -             * while nodes after this index should be rounded down -             * to the size of the previous stripe. -             */ -            if (i < eof_idx) -                tmp_offset = gf_roof(offset, -                                     fctx->stripe_size * fctx->stripe_count); -            else if (i > eof_idx) -                tmp_offset = gf_floor(offset, -                                      fctx->stripe_size * fctx->stripe_count); -            else -                tmp_offset = offset; - -            dest_offset = coalesced_offset(tmp_offset, fctx->stripe_size, -                                           fctx->stripe_count); -        } else { -            dest_offset = offset; -        } - -        STACK_WIND(frame, stripe_truncate_cbk, fctx->xl_array[i], -                   fctx->xl_array[i]->fops->truncate, loc, dest_offset, NULL); -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, struct iatt *preop, -                   struct iatt *postop, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } - -        if (op_ret == 0) { -            local->op_ret = 0; - -            if (FIRST_CHILD(this) == prev->this) { -                local->pre_buf = *preop; -                local->post_buf = *postop; -            } - -            local->prebuf_blocks += preop->ia_blocks; -            local->postbuf_blocks += postop->ia_blocks; - -            correct_file_size(preop, local->fctx, prev); -            correct_file_size(postop, local->fctx, prev); - -            if (local->prebuf_size < preop->ia_size) -                local->prebuf_size = preop->ia_size; -            if (local->postbuf_size < postop->ia_size) -                local->postbuf_size = postop->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret != -1) { -            local->pre_buf.ia_blocks = local->prebuf_blocks; -            local->pre_buf.ia_size = local->prebuf_size; -            local->post_buf.ia_blocks = local->postbuf_blocks; -            local->post_buf.ia_size = local->postbuf_size; -        } - -        STRIPE_STACK_UNWIND(setattr, frame, local->op_ret, local->op_errno, -                            &local->pre_buf, &local->post_buf, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, -               struct iatt *stbuf, int32_t valid, dict_t *xdata) -{ -    xlator_list_t *trav = NULL; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    if (!IA_ISDIR(loc->inode->ia_type) && !IA_ISREG(loc->inode->ia_type)) { -        local->call_count = 1; -        STACK_WIND(frame, stripe_setattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, NULL); -        return 0; -    } - -    if (IA_ISREG(loc->inode->ia_type)) { -        inode_ctx_get(loc->inode, this, (uint64_t *)&fctx); -        if (!fctx) -            goto err; -        local->fctx = fctx; -    } - -    local->call_count = priv->child_count; -    while (trav) { -        STACK_WIND(frame, stripe_setattr_cbk, trav->xlator, -                   trav->xlator->fops->setattr, loc, stbuf, valid, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, -                struct iatt *stbuf, int32_t valid, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    while (trav) { -        STACK_WIND(frame, stripe_setattr_cbk, trav->xlator, -                   trav->xlator->fops->fsetattr, fd, stbuf, valid, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_stack_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, struct iatt *buf, -                        struct iatt *preoldparent, struct iatt *postoldparent, -                        struct iatt *prenewparent, struct iatt *postnewparent, -                        dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } - -        if (op_ret == 0) { -            local->op_ret = 0; - -            local->stbuf.ia_blocks += buf->ia_blocks; -            local->preparent.ia_blocks += preoldparent->ia_blocks; -            local->postparent.ia_blocks += postoldparent->ia_blocks; -            local->pre_buf.ia_blocks += prenewparent->ia_blocks; -            local->post_buf.ia_blocks += postnewparent->ia_blocks; - -            correct_file_size(buf, local->fctx, prev); - -            if (local->stbuf.ia_size < buf->ia_size) -                local->stbuf.ia_size = buf->ia_size; - -            if (local->preparent.ia_size < preoldparent->ia_size) -                local->preparent.ia_size = preoldparent->ia_size; - -            if (local->postparent.ia_size < postoldparent->ia_size) -                local->postparent.ia_size = postoldparent->ia_size; - -            if (local->pre_buf.ia_size < prenewparent->ia_size) -                local->pre_buf.ia_size = prenewparent->ia_size; - -            if (local->post_buf.ia_size < postnewparent->ia_size) -                local->post_buf.ia_size = postnewparent->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        STRIPE_STACK_UNWIND(rename, frame, local->op_ret, local->op_errno, -                            &local->stbuf, &local->preparent, -                            &local->postparent, &local->pre_buf, -                            &local->post_buf, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_first_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, struct iatt *buf, -                        struct iatt *preoldparent, struct iatt *postoldparent, -                        struct iatt *prenewparent, struct iatt *postnewparent, -                        dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    xlator_list_t *trav = NULL; - -    if (!this || !frame || !frame->local) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        op_errno = EINVAL; -        goto unwind; -    } - -    if (op_ret == -1) { -        goto unwind; -    } - -    local = frame->local; -    trav = this->children; - -    local->stbuf = *buf; -    local->preparent = *preoldparent; -    local->postparent = *postoldparent; -    local->pre_buf = *prenewparent; -    local->post_buf = *postnewparent; - -    local->op_ret = 0; -    local->call_count--; - -    trav = trav->next; /* Skip first child */ -    while (trav) { -        STACK_WIND(frame, stripe_stack_rename_cbk, trav->xlator, -                   trav->xlator->fops->rename, &local->loc, &local->loc2, NULL); -        trav = trav->next; -    } -    return 0; - -unwind: -    STRIPE_STACK_UNWIND(rename, frame, -1, op_errno, buf, preoldparent, -                        postoldparent, prenewparent, postnewparent, NULL); -    return 0; -} - -int32_t -stripe_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -              dict_t *xdata) -{ -    stripe_private_t *priv = NULL; -    stripe_local_t *local = NULL; -    xlator_list_t *trav = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(oldloc, err); -    VALIDATE_OR_GOTO(oldloc->path, err); -    VALIDATE_OR_GOTO(oldloc->inode, err); -    VALIDATE_OR_GOTO(newloc, err); - -    priv = this->private; -    trav = this->children; - -    /* If any one node is down, don't allow rename */ -    if (priv->nodes_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    frame->local = local; - -    local->op_ret = -1; -    loc_copy(&local->loc, oldloc); -    loc_copy(&local->loc2, newloc); - -    local->call_count = priv->child_count; - -    if (IA_ISREG(oldloc->inode->ia_type)) { -        inode_ctx_get(oldloc->inode, this, (uint64_t *)&fctx); -        if (!fctx) -            goto err; -        local->fctx = fctx; -    } - -    STACK_WIND(frame, stripe_first_rename_cbk, trav->xlator, -               trav->xlator->fops->rename, oldloc, newloc, NULL); - -    return 0; -err: -    STRIPE_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, -                        NULL, NULL); -    return 0; -} -int32_t -stripe_first_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, -                        struct iatt *preparent, struct iatt *postparent, -                        dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    if (op_ret == -1) { -        gf_log(this->name, GF_LOG_DEBUG, "%s returned %s", prev->this->name, -               strerror(op_errno)); -        goto out; -    } -    local->op_ret = 0; -    local->preparent = *preparent; -    local->postparent = *postparent; -    local->preparent_blocks += preparent->ia_blocks; -    local->postparent_blocks += postparent->ia_blocks; - -    STRIPE_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, -                        &local->preparent, &local->postparent, xdata); -    return 0; -out: -    STRIPE_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); - -    return 0; -} - -int32_t -stripe_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, struct iatt *preparent, -                  struct iatt *postparent, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned %s", prev->this->name, -                   strerror(op_errno)); -            local->op_errno = op_errno; -            if (op_errno != ENOENT) { -                local->failed = 1; -                local->op_ret = op_ret; -            } -        } -    } -    UNLOCK(&frame->lock); - -    if (callcnt == 1) { -        if (local->failed) { -            op_errno = local->op_errno; -            goto out; -        } -        STACK_WIND(frame, stripe_first_unlink_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->unlink, &local->loc, local->xflag, -                   local->xdata); -    } -    return 0; -out: -    STRIPE_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); - -    return 0; -} - -int32_t -stripe_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, -              dict_t *xdata) -{ -    xlator_list_t *trav = NULL; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Don't unlink a file if a node is down */ -    if (priv->nodes_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    loc_copy(&local->loc, loc); -    local->xflag = xflag; - -    if (xdata) -        local->xdata = dict_ref(xdata); - -    frame->local = local; -    local->call_count = priv->child_count; -    trav = trav->next; /* Skip the first child */ - -    while (trav) { -        STACK_WIND(frame, stripe_unlink_cbk, trav->xlator, -                   trav->xlator->fops->unlink, loc, xflag, xdata); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_first_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, struct iatt *preparent, -                       struct iatt *postparent, dict_t *xdata) -{ -    stripe_local_t *local = NULL; - -    if (!this || !frame || !frame->local) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        op_errno = EINVAL; -        goto err; -    } - -    if (op_ret == -1) { -        goto err; -    } - -    local = frame->local; -    local->op_ret = 0; - -    local->call_count--; /* First child successful */ - -    local->preparent = *preparent; -    local->postparent = *postparent; -    local->preparent_size = preparent->ia_size; -    local->postparent_size = postparent->ia_size; -    local->preparent_blocks += preparent->ia_blocks; -    local->postparent_blocks += postparent->ia_blocks; - -    STRIPE_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, -                        &local->preparent, &local->postparent, xdata); -    return 0; -err: -    STRIPE_STACK_UNWIND(rmdir, frame, op_ret, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iatt *preparent, -                 struct iatt *postparent, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned %s", prev->this->name, -                   strerror(op_errno)); -            if (op_errno != ENOENT) -                local->failed = 1; -        } -    } -    UNLOCK(&frame->lock); - -    if (callcnt == 1) { -        if (local->failed) -            goto out; -        STACK_WIND(frame, stripe_first_rmdir_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->rmdir, &local->loc, local->flags, -                   NULL); -    } -    return 0; -out: -    STRIPE_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, -             dict_t *xdata) -{ -    xlator_list_t *trav = NULL; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* don't delete a directory if any of the subvolume is down */ -    if (priv->nodes_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    loc_copy(&local->loc, loc); -    local->flags = flags; -    local->call_count = priv->child_count; -    trav = trav->next; /* skip the first child */ - -    while (trav) { -        STACK_WIND(frame, stripe_rmdir_cbk, trav->xlator, -                   trav->xlator->fops->rmdir, loc, flags, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_mknod_ifreg_fail_unlink_cbk(call_frame_t *frame, void *cookie, -                                   xlator_t *this, int32_t op_ret, -                                   int32_t op_errno, struct iatt *preparent, -                                   struct iatt *postparent, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; - -    if (!this || !frame || !frame->local) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        STRIPE_STACK_UNWIND(mknod, frame, local->op_ret, local->op_errno, -                            local->inode, &local->stbuf, &local->preparent, -                            &local->postparent, NULL); -    } -out: -    return 0; -} - -/** - */ -int32_t -stripe_mknod_ifreg_setxattr_cbk(call_frame_t *frame, void *cookie, -                                xlator_t *this, int32_t op_ret, -                                int32_t op_errno, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    priv = this->private; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_ret = -1; -            local->op_errno = op_errno; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->op_ret == -1) { -            local->call_count = priv->child_count; -            while (trav) { -                STACK_WIND(frame, stripe_mknod_ifreg_fail_unlink_cbk, -                           trav->xlator, trav->xlator->fops->unlink, -                           &local->loc, 0, NULL); -                trav = trav->next; -            } -            return 0; -        } - -        STRIPE_STACK_UNWIND(mknod, frame, local->op_ret, local->op_errno, -                            local->inode, &local->stbuf, &local->preparent, -                            &local->postparent, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_mknod_ifreg_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, inode_t *inode, -                       struct iatt *buf, struct iatt *preparent, -                       struct iatt *postparent, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    call_frame_t *prev = NULL; -    xlator_list_t *trav = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    priv = this->private; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -            local->op_errno = op_errno; -        } -        if (op_ret >= 0) { -            local->op_ret = op_ret; - -            /* Can be used as a mechanism to understand if mknod -               was successful in at least one place */ -            if (gf_uuid_is_null(local->ia_gfid)) -                gf_uuid_copy(local->ia_gfid, buf->ia_gfid); - -            if (stripe_ctx_handle(this, prev, local, xdata)) -                gf_log(this->name, GF_LOG_ERROR, -                       "Error getting fctx info from dict"); - -            local->stbuf_blocks += buf->ia_blocks; -            local->preparent_blocks += preparent->ia_blocks; -            local->postparent_blocks += postparent->ia_blocks; - -            correct_file_size(buf, local->fctx, prev); - -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -            if (local->preparent_size < preparent->ia_size) -                local->preparent_size = preparent->ia_size; -            if (local->postparent_size < postparent->ia_size) -                local->postparent_size = postparent->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if ((local->op_ret == -1) && !gf_uuid_is_null(local->ia_gfid)) { -            /* ia_gfid set means, at least on one node 'mknod' -               is successful */ -            local->call_count = priv->child_count; -            trav = this->children; -            while (trav) { -                STACK_WIND(frame, stripe_mknod_ifreg_fail_unlink_cbk, -                           trav->xlator, trav->xlator->fops->unlink, -                           &local->loc, 0, NULL); -                trav = trav->next; -            } -            return 0; -        } - -        if (local->op_ret != -1) { -            local->preparent.ia_blocks = local->preparent_blocks; -            local->preparent.ia_size = local->preparent_size; -            local->postparent.ia_blocks = local->postparent_blocks; -            local->postparent.ia_size = local->postparent_size; -            local->stbuf.ia_size = local->stbuf_size; -            local->stbuf.ia_blocks = local->stbuf_blocks; -            inode_ctx_put(local->inode, this, (uint64_t)(long)local->fctx); -        } -        STRIPE_STACK_UNWIND(mknod, frame, local->op_ret, local->op_errno, -                            local->inode, &local->stbuf, &local->preparent, -                            &local->postparent, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_mknod_first_ifreg_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                             int32_t op_ret, int32_t op_errno, inode_t *inode, -                             struct iatt *buf, struct iatt *preparent, -                             struct iatt *postparent, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    call_frame_t *prev = NULL; -    xlator_list_t *trav = NULL; -    int i = 1; -    dict_t *dict = NULL; -    int ret = 0; -    int need_unref = 0; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    priv = this->private; -    local = frame->local; -    trav = this->children; - -    local->call_count--; - -    if (op_ret == -1) { -        gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -               prev->this->name, strerror(op_errno)); -        local->failed = 1; -        local->op_errno = op_errno; -        goto out; -    } - -    local->op_ret = op_ret; - -    local->stbuf = *buf; -    local->preparent = *preparent; -    local->postparent = *postparent; - -    if (gf_uuid_is_null(local->ia_gfid)) -        gf_uuid_copy(local->ia_gfid, buf->ia_gfid); -    local->preparent.ia_blocks = local->preparent_blocks; -    local->preparent.ia_size = local->preparent_size; -    local->postparent.ia_blocks = local->postparent_blocks; -    local->postparent.ia_size = local->postparent_size; -    local->stbuf.ia_size = local->stbuf_size; -    local->stbuf.ia_blocks = local->stbuf_blocks; - -    trav = trav->next; -    while (trav) { -        if (priv->xattr_supported) { -            dict = dict_new(); -            if (!dict) { -                gf_log(this->name, GF_LOG_ERROR, "failed to allocate dict %s", -                       local->loc.path); -            } -            need_unref = 1; - -            dict_copy(local->xattr, dict); - -            ret = stripe_xattr_request_build(this, dict, local->stripe_size, -                                             priv->child_count, i, -                                             priv->coalesce); -            if (ret) -                gf_log(this->name, GF_LOG_ERROR, -                       "Failed to build xattr request"); - -        } else { -            dict = local->xattr; -        } - -        STACK_WIND(frame, stripe_mknod_ifreg_cbk, trav->xlator, -                   trav->xlator->fops->mknod, &local->loc, local->mode, -                   local->rdev, 0, dict); -        trav = trav->next; -        i++; - -        if (dict && need_unref) -            dict_unref(dict); -    } - -    return 0; - -out: - -    STRIPE_STACK_UNWIND(mknod, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, -                        NULL); -    return 0; -} - -int32_t -stripe_single_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, inode_t *inode, -                        struct iatt *buf, struct iatt *preparent, -                        struct iatt *postparent, dict_t *xdata) -{ -    STRIPE_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -    return 0; -} - -int -stripe_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, -             dev_t rdev, mode_t umask, dict_t *xdata) -{ -    stripe_private_t *priv = NULL; -    stripe_local_t *local = NULL; -    int32_t op_errno = EINVAL; -    int32_t i = 0; -    dict_t *dict = NULL; -    int ret = 0; -    int need_unref = 0; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    if (S_ISREG(mode)) { -        /* NOTE: on older kernels (older than 2.6.9), -           creat() fops is sent as mknod() + open(). Hence handling -           S_IFREG files is necessary */ -        if (priv->nodes_down) { -            gf_log(this->name, GF_LOG_WARNING, "Some node down, returning EIO"); -            op_errno = EIO; -            goto err; -        } - -        /* Initialization */ -        local = mem_get0(this->local_pool); -        if (!local) { -            op_errno = ENOMEM; -            goto err; -        } -        local->op_ret = -1; -        local->op_errno = ENOTCONN; -        local->stripe_size = stripe_get_matching_bs(loc->path, priv); -        frame->local = local; -        local->inode = inode_ref(loc->inode); -        loc_copy(&local->loc, loc); -        local->xattr = dict_copy_with_ref(xdata, NULL); -        local->mode = mode; -        local->umask = umask; -        local->rdev = rdev; - -        /* Every time in stripe lookup, all child nodes should -           be looked up */ -        local->call_count = priv->child_count; - -        if (priv->xattr_supported) { -            dict = dict_new(); -            if (!dict) { -                gf_log(this->name, GF_LOG_ERROR, "failed to allocate dict %s", -                       loc->path); -            } -            need_unref = 1; - -            dict_copy(xdata, dict); - -            ret = stripe_xattr_request_build(this, dict, local->stripe_size, -                                             priv->child_count, i, -                                             priv->coalesce); -            if (ret) -                gf_log(this->name, GF_LOG_ERROR, -                       "failed to build xattr request"); -        } else { -            dict = xdata; -        } - -        STACK_WIND(frame, stripe_mknod_first_ifreg_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, -                   dict); - -        if (dict && need_unref) -            dict_unref(dict); -        return 0; -    } - -    STACK_WIND(frame, stripe_single_mknod_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); - -    return 0; -err: -    STRIPE_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, -                        NULL); -    return 0; -} - -int32_t -stripe_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, inode_t *inode, -                 struct iatt *buf, struct iatt *preparent, -                 struct iatt *postparent, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } - -        if (op_ret >= 0) { -            local->op_ret = 0; - -            local->stbuf_blocks += buf->ia_blocks; -            local->preparent_blocks += preparent->ia_blocks; -            local->postparent_blocks += postparent->ia_blocks; - -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -            if (local->preparent_size < preparent->ia_size) -                local->preparent_size = preparent->ia_size; -            if (local->postparent_size < postparent->ia_size) -                local->postparent_size = postparent->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed != -1) { -            local->preparent.ia_blocks = local->preparent_blocks; -            local->preparent.ia_size = local->preparent_size; -            local->postparent.ia_blocks = local->postparent_blocks; -            local->postparent.ia_size = local->postparent_size; -            local->stbuf.ia_size = local->stbuf_size; -            local->stbuf.ia_blocks = local->stbuf_blocks; -        } -        STRIPE_STACK_UNWIND(mkdir, frame, local->op_ret, local->op_errno, -                            local->inode, &local->stbuf, &local->preparent, -                            &local->postparent, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_first_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, inode_t *inode, -                       struct iatt *buf, struct iatt *preparent, -                       struct iatt *postparent, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; -    xlator_list_t *trav = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; -    trav = this->children; - -    local->call_count--; /* first child is successful */ -    trav = trav->next;   /* skip first child */ - -    if (op_ret == -1) { -        gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -               prev->this->name, strerror(op_errno)); -        local->op_errno = op_errno; -        goto out; -    } - -    local->op_ret = 0; - -    local->inode = inode_ref(inode); -    local->stbuf = *buf; -    local->postparent = *postparent; -    local->preparent = *preparent; - -    local->stbuf_blocks += buf->ia_blocks; -    local->preparent_blocks += preparent->ia_blocks; -    local->postparent_blocks += postparent->ia_blocks; - -    local->stbuf_size = buf->ia_size; -    local->preparent_size = preparent->ia_size; -    local->postparent_size = postparent->ia_size; - -    while (trav) { -        STACK_WIND(frame, stripe_mkdir_cbk, trav->xlator, -                   trav->xlator->fops->mkdir, &local->loc, local->mode, -                   local->umask, local->xdata); -        trav = trav->next; -    } -    return 0; -out: -    STRIPE_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, -                        NULL); - -    return 0; -} - -int -stripe_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, -             mode_t umask, dict_t *xdata) -{ -    stripe_private_t *priv = NULL; -    stripe_local_t *local = NULL; -    xlator_list_t *trav = NULL; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    local->call_count = priv->child_count; -    if (xdata) -        local->xdata = dict_ref(xdata); -    local->mode = mode; -    local->umask = umask; -    loc_copy(&local->loc, loc); -    frame->local = local; - -    /* Every time in stripe lookup, all child nodes should be looked up */ -    STACK_WIND(frame, stripe_first_mkdir_cbk, trav->xlator, -               trav->xlator->fops->mkdir, loc, mode, umask, xdata); - -    return 0; -err: -    STRIPE_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, -                        NULL); -    return 0; -} - -int32_t -stripe_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, inode_t *inode, -                struct iatt *buf, struct iatt *preparent, -                struct iatt *postparent, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; -    stripe_fd_ctx_t *fctx = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } - -        if (op_ret >= 0) { -            local->op_ret = 0; - -            if (IA_ISREG(inode->ia_type)) { -                inode_ctx_get(inode, this, (uint64_t *)&fctx); -                if (!fctx) { -                    gf_log(this->name, GF_LOG_ERROR, -                           "failed to get stripe context"); -                    op_ret = -1; -                    op_errno = EINVAL; -                } -            } - -            if (FIRST_CHILD(this) == prev->this) { -                local->inode = inode_ref(inode); -                local->stbuf = *buf; -                local->postparent = *postparent; -                local->preparent = *preparent; -            } -            local->stbuf_blocks += buf->ia_blocks; -            local->preparent_blocks += preparent->ia_blocks; -            local->postparent_blocks += postparent->ia_blocks; - -            correct_file_size(buf, fctx, prev); - -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -            if (local->preparent_size < preparent->ia_size) -                local->preparent_size = preparent->ia_size; -            if (local->postparent_size < postparent->ia_size) -                local->postparent_size = postparent->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret != -1) { -            local->preparent.ia_blocks = local->preparent_blocks; -            local->preparent.ia_size = local->preparent_size; -            local->postparent.ia_blocks = local->postparent_blocks; -            local->postparent.ia_size = local->postparent_size; -            local->stbuf.ia_size = local->stbuf_size; -            local->stbuf.ia_blocks = local->stbuf_blocks; -        } -        STRIPE_STACK_UNWIND(link, frame, local->op_ret, local->op_errno, -                            local->inode, &local->stbuf, &local->preparent, -                            &local->postparent, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -            dict_t *xdata) -{ -    xlator_list_t *trav = NULL; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(oldloc, err); -    VALIDATE_OR_GOTO(oldloc->path, err); -    VALIDATE_OR_GOTO(oldloc->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* If any one node is down, don't allow link operation */ -    if (priv->nodes_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    /* Every time in stripe lookup, all child -       nodes should be looked up */ -    while (trav) { -        STACK_WIND(frame, stripe_link_cbk, trav->xlator, -                   trav->xlator->fops->link, oldloc, newloc, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, -                        NULL); -    return 0; -} - -int32_t -stripe_create_fail_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                              int32_t op_ret, int32_t op_errno, -                              struct iatt *preparent, struct iatt *postparent, -                              dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; - -    if (!this || !frame || !frame->local) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        STRIPE_STACK_UNWIND(create, frame, local->op_ret, local->op_errno, -                            local->fd, local->inode, &local->stbuf, -                            &local->preparent, &local->postparent, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, -                  struct iatt *buf, struct iatt *preparent, -                  struct iatt *postparent, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    call_frame_t *prev = NULL; -    xlator_list_t *trav = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    priv = this->private; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->failed = 1; -            local->op_errno = op_errno; -        } - -        if (op_ret >= 0) { -            if (IA_ISREG(buf->ia_type)) { -                if (stripe_ctx_handle(this, prev, local, xdata)) -                    gf_log(this->name, GF_LOG_ERROR, -                           "Error getting fctx info from " -                           "dict"); -            } - -            local->op_ret = op_ret; - -            local->stbuf_blocks += buf->ia_blocks; -            local->preparent_blocks += preparent->ia_blocks; -            local->postparent_blocks += postparent->ia_blocks; - -            correct_file_size(buf, local->fctx, prev); - -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -            if (local->preparent_size < preparent->ia_size) -                local->preparent_size = preparent->ia_size; -            if (local->postparent_size < postparent->ia_size) -                local->postparent_size = postparent->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret == -1) { -            local->call_count = priv->child_count; -            trav = this->children; -            while (trav) { -                STACK_WIND(frame, stripe_create_fail_unlink_cbk, trav->xlator, -                           trav->xlator->fops->unlink, &local->loc, 0, NULL); -                trav = trav->next; -            } - -            return 0; -        } - -        if (local->op_ret >= 0) { -            local->preparent.ia_blocks = local->preparent_blocks; -            local->preparent.ia_size = local->preparent_size; -            local->postparent.ia_blocks = local->postparent_blocks; -            local->postparent.ia_size = local->postparent_size; -            local->stbuf.ia_size = local->stbuf_size; -            local->stbuf.ia_blocks = local->stbuf_blocks; - -            stripe_copy_xl_array(local->fctx->xl_array, priv->xl_array, -                                 local->fctx->stripe_count); -            inode_ctx_put(local->inode, this, (uint64_t)(uintptr_t)local->fctx); -        } - -        /* Create itself has failed.. so return -           without setxattring */ -        STRIPE_STACK_UNWIND(create, frame, local->op_ret, local->op_errno, -                            local->fd, local->inode, &local->stbuf, -                            &local->preparent, &local->postparent, NULL); -    } - -out: -    return 0; -} - -int32_t -stripe_first_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, fd_t *fd, -                        inode_t *inode, struct iatt *buf, -                        struct iatt *preparent, struct iatt *postparent, -                        dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    call_frame_t *prev = NULL; -    xlator_list_t *trav = NULL; -    int i = 1; -    dict_t *dict = NULL; -    loc_t *loc = NULL; -    int32_t need_unref = 0; -    int32_t ret = -1; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    priv = this->private; -    local = frame->local; -    trav = this->children; -    loc = &local->loc; - -    --local->call_count; - -    if (op_ret == -1) { -        gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -               prev->this->name, strerror(op_errno)); -        local->failed = 1; -        local->op_errno = op_errno; -    } - -    local->op_ret = 0; -    /* Get the mapping in inode private */ -    /* Get the stat buf right */ -    local->stbuf = *buf; -    local->preparent = *preparent; -    local->postparent = *postparent; - -    local->stbuf_blocks += buf->ia_blocks; -    local->preparent_blocks += preparent->ia_blocks; -    local->postparent_blocks += postparent->ia_blocks; - -    if (local->stbuf_size < buf->ia_size) -        local->stbuf_size = buf->ia_size; -    if (local->preparent_size < preparent->ia_size) -        local->preparent_size = preparent->ia_size; -    if (local->postparent_size < postparent->ia_size) -        local->postparent_size = postparent->ia_size; - -    if (local->failed) -        local->op_ret = -1; - -    if (local->op_ret == -1) { -        local->call_count = 1; -        STACK_WIND(frame, stripe_create_fail_unlink_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->unlink, &local->loc, 0, NULL); -        return 0; -    } - -    if (local->op_ret >= 0) { -        local->preparent.ia_blocks = local->preparent_blocks; -        local->preparent.ia_size = local->preparent_size; -        local->postparent.ia_blocks = local->postparent_blocks; -        local->postparent.ia_size = local->postparent_size; -        local->stbuf.ia_size = local->stbuf_size; -        local->stbuf.ia_blocks = local->stbuf_blocks; -    } - -    /* Send a setxattr request to nodes where the -       files are created */ -    trav = trav->next; -    while (trav) { -        if (priv->xattr_supported) { -            dict = dict_new(); -            if (!dict) { -                gf_log(this->name, GF_LOG_ERROR, "failed to allocate dict %s", -                       loc->path); -            } -            need_unref = 1; - -            dict_copy(local->xattr, dict); - -            ret = stripe_xattr_request_build(this, dict, local->stripe_size, -                                             priv->child_count, i, -                                             priv->coalesce); -            if (ret) -                gf_log(this->name, GF_LOG_ERROR, -                       "failed to build xattr request"); -        } else { -            dict = local->xattr; -        } - -        STACK_WIND(frame, stripe_create_cbk, trav->xlator, -                   trav->xlator->fops->create, &local->loc, local->flags, -                   local->mode, local->umask, local->fd, dict); -        trav = trav->next; -        if (need_unref && dict) -            dict_unref(dict); -        i++; -    } - -out: -    return 0; -} - -/** - * stripe_create - If a block-size is specified for the 'name', create the - *    file in all the child nodes. If not, create it in only first child. - * - * @name- complete path of the file to be created. - */ -int32_t -stripe_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -              mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) -{ -    stripe_private_t *priv = NULL; -    stripe_local_t *local = NULL; -    int32_t op_errno = EINVAL; -    int ret = 0; -    int need_unref = 0; -    int i = 0; -    dict_t *dict = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; - -    /* files created in O_APPEND mode does not allow lseek() on fd */ -    flags &= ~O_APPEND; - -    if (priv->first_child_down || priv->nodes_down) { -        gf_log(this->name, GF_LOG_DEBUG, "First node down, returning EIO"); -        op_errno = EIO; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    local->op_errno = ENOTCONN; -    local->stripe_size = stripe_get_matching_bs(loc->path, priv); -    frame->local = local; -    local->inode = inode_ref(loc->inode); -    loc_copy(&local->loc, loc); -    local->fd = fd_ref(fd); -    local->flags = flags; -    local->mode = mode; -    local->umask = umask; -    if (xdata) -        local->xattr = dict_ref(xdata); - -    local->call_count = priv->child_count; -    /* Send a setxattr request to nodes where the -       files are created */ - -    if (priv->xattr_supported) { -        dict = dict_new(); -        if (!dict) { -            gf_log(this->name, GF_LOG_ERROR, "failed to allocate dict %s", -                   loc->path); -        } -        need_unref = 1; - -        dict_copy(xdata, dict); - -        ret = stripe_xattr_request_build(this, dict, local->stripe_size, -                                         priv->child_count, i, priv->coalesce); -        if (ret) -            gf_log(this->name, GF_LOG_ERROR, "failed to build xattr request"); -    } else { -        dict = xdata; -    } - -    STACK_WIND(frame, stripe_first_create_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, -               dict); - -    if (need_unref && dict) -        dict_unref(dict); - -    return 0; -err: -    STRIPE_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, -                        NULL, xdata); -    return 0; -} - -int32_t -stripe_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -            local->op_errno = op_errno; -        } - -        if (op_ret >= 0) -            local->op_ret = op_ret; -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        STRIPE_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, -                            local->fd, xdata); -    } -out: -    return 0; -} - -/** - * stripe_open - - */ -int32_t -stripe_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -            fd_t *fd, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    /* files opened in O_APPEND mode does not allow lseek() on fd */ -    flags &= ~O_APPEND; - -    local->fd = fd_ref(fd); -    frame->local = local; -    loc_copy(&local->loc, loc); - -    /* Striped files */ -    local->flags = flags; -    local->call_count = priv->child_count; -    local->stripe_size = stripe_get_matching_bs(loc->path, priv); - -    while (trav) { -        STACK_WIND(frame, stripe_open_cbk, trav->xlator, -                   trav->xlator->fops->open, &local->loc, local->flags, -                   local->fd, xdata); -        trav = trav->next; -    } -    return 0; -err: -    STRIPE_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL); -    return 0; -} - -int32_t -stripe_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_ret = -1; -            local->op_errno = op_errno; -        } - -        if (op_ret >= 0) -            local->op_ret = op_ret; -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        STRIPE_STACK_UNWIND(opendir, frame, local->op_ret, local->op_errno, -                            local->fd, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, -               dict_t *xdata) -{ -    xlator_list_t *trav = NULL; -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    frame->local = local; -    local->call_count = priv->child_count; -    local->fd = fd_ref(fd); - -    while (trav) { -        STACK_WIND(frame, stripe_opendir_cbk, trav->xlator, -                   trav->xlator->fops->opendir, loc, fd, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(opendir, frame, -1, op_errno, NULL, NULL); -    return 0; -} - -int32_t -stripe_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct gf_flock *lock, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } -        if (op_ret >= 0) { -            if (FIRST_CHILD(this) == prev->this) { -                /* First successful call, copy the *lock */ -                local->op_ret = op_ret; -                local->lock = *lock; -            } -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; -        STRIPE_STACK_UNWIND(lk, frame, local->op_ret, local->op_errno, -                            &local->lock, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, -          struct gf_flock *lock, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    xlator_list_t *trav = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    trav = this->children; -    priv = this->private; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    while (trav) { -        STACK_WIND(frame, stripe_lk_cbk, trav->xlator, trav->xlator->fops->lk, -                   fd, cmd, lock, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL); -    return 0; -} - -int32_t -stripe_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned %s", prev->this->name, -                   strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } -        if (op_ret >= 0) -            local->op_ret = op_ret; -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        STRIPE_STACK_UNWIND(flush, frame, local->op_ret, local->op_errno, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    while (trav) { -        STACK_WIND(frame, stripe_flush_cbk, trav->xlator, -                   trav->xlator->fops->flush, fd, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(flush, frame, -1, op_errno, NULL); -    return 0; -} - -int32_t -stripe_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                 struct iatt *postbuf, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned %s", prev->this->name, -                   strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } -        if (op_ret >= 0) { -            local->op_ret = op_ret; -            if (FIRST_CHILD(this) == prev->this) { -                local->pre_buf = *prebuf; -                local->post_buf = *postbuf; -            } -            local->prebuf_blocks += prebuf->ia_blocks; -            local->postbuf_blocks += postbuf->ia_blocks; - -            correct_file_size(prebuf, local->fctx, prev); -            correct_file_size(postbuf, local->fctx, prev); - -            if (local->prebuf_size < prebuf->ia_size) -                local->prebuf_size = prebuf->ia_size; - -            if (local->postbuf_size < postbuf->ia_size) -                local->postbuf_size = postbuf->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret != -1) { -            local->pre_buf.ia_blocks = local->prebuf_blocks; -            local->pre_buf.ia_size = local->prebuf_size; -            local->post_buf.ia_blocks = local->postbuf_blocks; -            local->post_buf.ia_size = local->postbuf_size; -        } - -        STRIPE_STACK_UNWIND(fsync, frame, local->op_ret, local->op_errno, -                            &local->pre_buf, &local->post_buf, NULL); -    } -out: -    return 0; -} - -int32_t -stripe_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, -             dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    frame->local = local; - -    inode_ctx_get(fd->inode, this, (uint64_t *)&fctx); -    if (!fctx) { -        op_errno = EINVAL; -        goto err; -    } -    local->fctx = fctx; -    local->op_ret = -1; -    local->call_count = priv->child_count; - -    while (trav) { -        STACK_WIND(frame, stripe_fsync_cbk, trav->xlator, -                   trav->xlator->fops->fsync, fd, flags, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iatt *buf, -                 dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned error %s", -                   prev->this->name, strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } - -        if (op_ret == 0) { -            local->op_ret = 0; - -            if (FIRST_CHILD(this) == prev->this) -                local->stbuf = *buf; - -            local->stbuf_blocks += buf->ia_blocks; - -            correct_file_size(buf, local->fctx, prev); - -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        if (local->op_ret != -1) { -            local->stbuf.ia_size = local->stbuf_size; -            local->stbuf.ia_blocks = local->stbuf_blocks; -        } - -        STRIPE_STACK_UNWIND(fstat, frame, local->op_ret, local->op_errno, -                            &local->stbuf, NULL); -    } - -out: -    return 0; -} - -int32_t -stripe_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    if (IA_ISREG(fd->inode->ia_type)) { -        inode_ctx_get(fd->inode, this, (uint64_t *)&fctx); -        if (!fctx) -            goto err; -        local->fctx = fctx; -    } - -    while (trav) { -        STACK_WIND(frame, stripe_fstat_cbk, trav->xlator, -                   trav->xlator->fops->fstat, fd, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL); -    return 0; -} - -int32_t -stripe_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -                 dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int i, eof_idx; -    off_t dest_offset, tmp_offset; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    priv = this->private; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    inode_ctx_get(fd->inode, this, (uint64_t *)&fctx); -    if (!fctx) { -        gf_log(this->name, GF_LOG_ERROR, "no stripe context"); -        op_errno = EINVAL; -        goto err; -    } -    if (!fctx->stripe_count) { -        gf_log(this->name, GF_LOG_ERROR, "no stripe count"); -        op_errno = EINVAL; -        goto err; -    } - -    local->fctx = fctx; -    eof_idx = (offset / fctx->stripe_size) % fctx->stripe_count; - -    for (i = 0; i < fctx->stripe_count; i++) { -        if (!fctx->xl_array[i]) { -            gf_log(this->name, GF_LOG_ERROR, -                   "no xlator at index " -                   "%d", -                   i); -            op_errno = EINVAL; -            goto err; -        } - -        if (fctx->stripe_coalesce) { -            if (i < eof_idx) -                tmp_offset = gf_roof(offset, -                                     fctx->stripe_size * fctx->stripe_count); -            else if (i > eof_idx) -                tmp_offset = gf_floor(offset, -                                      fctx->stripe_size * fctx->stripe_count); -            else -                tmp_offset = offset; - -            dest_offset = coalesced_offset(tmp_offset, fctx->stripe_size, -                                           fctx->stripe_count); -        } else { -            dest_offset = offset; -        } - -        STACK_WIND(frame, stripe_truncate_cbk, fctx->xl_array[i], -                   fctx->xl_array[i]->fops->ftruncate, fd, dest_offset, NULL); -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; - -        if (op_ret == -1) { -            gf_log(this->name, GF_LOG_DEBUG, "%s returned %s", prev->this->name, -                   strerror(op_errno)); -            local->op_errno = op_errno; -            if ((op_errno != ENOENT) || (prev->this == FIRST_CHILD(this))) -                local->failed = 1; -        } -        if (op_ret >= 0) -            local->op_ret = op_ret; -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (local->failed) -            local->op_ret = -1; - -        STRIPE_STACK_UNWIND(fsyncdir, frame, local->op_ret, local->op_errno, -                            NULL); -    } -out: -    return 0; -} - -int32_t -stripe_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, -                dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    int32_t op_errno = 1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    local->call_count = priv->child_count; - -    while (trav) { -        STACK_WIND(frame, stripe_fsyncdir_cbk, trav->xlator, -                   trav->xlator->fops->fsyncdir, fd, flags, NULL); -        trav = trav->next; -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(fsyncdir, frame, -1, op_errno, NULL); -    return 0; -} - -int32_t -stripe_readv_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, struct iatt *buf, -                       dict_t *xdata) -{ -    int32_t i = 0; -    int32_t callcnt = 0; -    int32_t count = 0; -    stripe_local_t *local = NULL; -    struct iovec *vec = NULL; -    struct iatt tmp_stbuf = { -        0, -    }; -    struct iobref *tmp_iobref = NULL; -    struct iobuf *iobuf = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    local = frame->local; -    prev = cookie; - -    LOCK(&frame->lock); -    { -        callcnt = --local->call_count; -        if (op_ret != -1) { -            correct_file_size(buf, local->fctx, prev); -            if (local->stbuf_size < buf->ia_size) -                local->stbuf_size = buf->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        op_ret = 0; - -        /* Keep extra space for filling in '\0's */ -        vec = GF_CALLOC((local->count * 2), sizeof(struct iovec), -                        gf_stripe_mt_iovec); -        if (!vec) { -            op_ret = -1; -            goto done; -        } - -        for (i = 0; i < local->wind_count; i++) { -            if (local->replies[i].op_ret) { -                memcpy((vec + count), local->replies[i].vector, -                       (local->replies[i].count * sizeof(struct iovec))); -                count += local->replies[i].count; -                op_ret += local->replies[i].op_ret; -            } -            if ((local->replies[i].op_ret < local->replies[i].requested_size) && -                (local->stbuf_size > (local->offset + op_ret))) { -                /* Fill in 0s here */ -                vec[count].iov_len = (local->replies[i].requested_size - -                                      local->replies[i].op_ret); -                iobuf = iobuf_get2(this->ctx->iobuf_pool, vec[count].iov_len); -                if (!iobuf) { -                    gf_log(this->name, GF_LOG_ERROR, "Out of memory."); -                    op_ret = -1; -                    op_errno = ENOMEM; -                    goto done; -                } -                memset(iobuf->ptr, 0, vec[count].iov_len); -                vec[count].iov_base = iobuf->ptr; - -                iobref_add(local->iobref, iobuf); -                iobuf_unref(iobuf); - -                op_ret += vec[count].iov_len; -                count++; -            } -            GF_FREE(local->replies[i].vector); -        } - -        /* ENOENT signals EOF to the NFS-server */ -        if (op_ret != -1 && op_ret < local->readv_size && -            (local->offset + op_ret == buf->ia_size)) -            op_errno = ENOENT; - -        /* FIXME: notice that st_ino, and st_dev (gen) will be -         * different than what inode will have. Make sure this doesn't -         * cause any bugs at higher levels */ -        memcpy(&tmp_stbuf, &local->replies[0].stbuf, sizeof(struct iatt)); -        tmp_stbuf.ia_size = local->stbuf_size; - -    done: -        GF_FREE(local->replies); -        tmp_iobref = local->iobref; -        STRIPE_STACK_UNWIND(readv, frame, op_ret, op_errno, vec, count, -                            &tmp_stbuf, tmp_iobref, NULL); - -        iobref_unref(tmp_iobref); -        GF_FREE(vec); -    } -out: -    return 0; -} - -/** - * stripe_readv_cbk - get all the striped reads, and order it properly, send it - *        to above layer after putting it in a single vector. - */ -int32_t -stripe_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iovec *vector, -                 int32_t count, struct iatt *stbuf, struct iobref *iobref, -                 dict_t *xdata) -{ -    int32_t index = 0; -    int32_t callcnt = 0; -    int32_t final_count = 0; -    int32_t need_to_check_proper_size = 0; -    call_frame_t *mframe = NULL; -    stripe_local_t *mlocal = NULL; -    stripe_local_t *local = NULL; -    struct iovec *final_vec = NULL; -    struct iatt tmp_stbuf = { -        0, -    }; -    struct iatt *tmp_stbuf_p = NULL;  // need it for a warning -    struct iobref *tmp_iobref = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    call_frame_t *prev = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto end; -    } - -    local = frame->local; -    index = local->node_index; -    prev = cookie; -    mframe = local->orig_frame; -    if (!mframe) -        goto out; - -    mlocal = mframe->local; -    if (!mlocal) -        goto out; - -    fctx = mlocal->fctx; - -    LOCK(&mframe->lock); -    { -        mlocal->replies[index].op_ret = op_ret; -        mlocal->replies[index].op_errno = op_errno; -        mlocal->replies[index].requested_size = local->readv_size; -        if (op_ret >= 0) { -            mlocal->replies[index].stbuf = *stbuf; -            mlocal->replies[index].count = count; -            mlocal->replies[index].vector = iov_dup(vector, count); - -            correct_file_size(stbuf, fctx, prev); - -            if (local->stbuf_size < stbuf->ia_size) -                local->stbuf_size = stbuf->ia_size; -            local->stbuf_blocks += stbuf->ia_blocks; - -            if (!mlocal->iobref) -                mlocal->iobref = iobref_new(); -            iobref_merge(mlocal->iobref, iobref); -        } -        callcnt = ++mlocal->call_count; -    } -    UNLOCK(&mframe->lock); - -    if (callcnt == mlocal->wind_count) { -        op_ret = 0; - -        for (index = 0; index < mlocal->wind_count; index++) { -            /* check whether each stripe returned -             * 'expected' number of bytes */ -            if (mlocal->replies[index].op_ret == -1) { -                op_ret = -1; -                op_errno = mlocal->replies[index].op_errno; -                break; -            } -            /* TODO: handle the 'holes' within the read range -               properly */ -            if (mlocal->replies[index].op_ret < -                mlocal->replies[index].requested_size) { -                need_to_check_proper_size = 1; -            } - -            op_ret += mlocal->replies[index].op_ret; -            mlocal->count += mlocal->replies[index].count; -        } -        if (op_ret == -1) -            goto done; -        if (need_to_check_proper_size) -            goto check_size; - -        final_vec = GF_CALLOC(mlocal->count, sizeof(struct iovec), -                              gf_stripe_mt_iovec); - -        if (!final_vec) { -            op_ret = -1; -            goto done; -        } - -        for (index = 0; index < mlocal->wind_count; index++) { -            memcpy((final_vec + final_count), mlocal->replies[index].vector, -                   (mlocal->replies[index].count * sizeof(struct iovec))); -            final_count += mlocal->replies[index].count; -            GF_FREE(mlocal->replies[index].vector); -        } - -        /* FIXME: notice that st_ino, and st_dev (gen) will be -         * different than what inode will have. Make sure this doesn't -         * cause any bugs at higher levels */ -        memcpy(&tmp_stbuf, &mlocal->replies[0].stbuf, sizeof(struct iatt)); -        tmp_stbuf.ia_size = local->stbuf_size; -        tmp_stbuf.ia_blocks = local->stbuf_blocks; - -    done: -        /* */ -        GF_FREE(mlocal->replies); -        tmp_iobref = mlocal->iobref; -        /* work around for nfs truncated read. Bug 3774 */ -        tmp_stbuf_p = &tmp_stbuf; -        WIPE(tmp_stbuf_p); -        STRIPE_STACK_UNWIND(readv, mframe, op_ret, op_errno, final_vec, -                            final_count, &tmp_stbuf, tmp_iobref, NULL); - -        iobref_unref(tmp_iobref); -        GF_FREE(final_vec); -    } - -    goto out; - -check_size: -    mlocal->call_count = fctx->stripe_count; - -    for (index = 0; index < fctx->stripe_count; index++) { -        STACK_WIND(mframe, stripe_readv_fstat_cbk, (fctx->xl_array[index]), -                   (fctx->xl_array[index])->fops->fstat, mlocal->fd, NULL); -    } - -out: -    STRIPE_STACK_DESTROY(frame); -end: -    return 0; -} - -int32_t -stripe_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -             off_t offset, uint32_t flags, dict_t *xdata) -{ -    int32_t op_errno = EINVAL; -    int32_t idx = 0; -    int32_t index = 0; -    int32_t num_stripe = 0; -    int32_t off_index = 0; -    size_t frame_size = 0; -    off_t rounded_end = 0; -    uint64_t tmp_fctx = 0; -    uint64_t stripe_size = 0; -    off_t rounded_start = 0; -    off_t frame_offset = offset; -    off_t dest_offset = 0; -    stripe_local_t *local = NULL; -    call_frame_t *rframe = NULL; -    stripe_local_t *rlocal = NULL; -    stripe_fd_ctx_t *fctx = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    inode_ctx_get(fd->inode, this, &tmp_fctx); -    if (!tmp_fctx) { -        op_errno = EBADFD; -        goto err; -    } -    fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; -    stripe_size = fctx->stripe_size; - -    STRIPE_VALIDATE_FCTX(fctx, err); - -    if (!stripe_size) { -        gf_log(this->name, GF_LOG_DEBUG, "Wrong stripe size for the file"); -        goto err; -    } -    /* The file is stripe across the child nodes. Send the read request -     * to the child nodes appropriately after checking which region of -     * the file is in which child node. Always '0-<stripe_size>' part of -     * the file resides in the first child. -     */ -    rounded_start = gf_floor(offset, stripe_size); -    rounded_end = gf_roof(offset + size, stripe_size); -    num_stripe = (rounded_end - rounded_start) / stripe_size; - -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    frame->local = local; - -    /* This is where all the vectors should be copied. */ -    local->replies = GF_CALLOC(num_stripe, sizeof(struct stripe_replies), -                               gf_stripe_mt_stripe_replies); -    if (!local->replies) { -        op_errno = ENOMEM; -        goto err; -    } - -    off_index = (offset / stripe_size) % fctx->stripe_count; -    local->wind_count = num_stripe; -    local->readv_size = size; -    local->offset = offset; -    local->fd = fd_ref(fd); -    local->fctx = fctx; - -    for (index = off_index; index < (num_stripe + off_index); index++) { -        rframe = copy_frame(frame); -        rlocal = mem_get0(this->local_pool); -        if (!rlocal) { -            op_errno = ENOMEM; -            goto err; -        } - -        frame_size = min(gf_roof(frame_offset + 1, stripe_size), -                         (offset + size)) - -                     frame_offset; - -        rlocal->node_index = index - off_index; -        rlocal->orig_frame = frame; -        rlocal->readv_size = frame_size; -        rframe->local = rlocal; -        idx = (index % fctx->stripe_count); - -        if (fctx->stripe_coalesce) -            dest_offset = coalesced_offset(frame_offset, stripe_size, -                                           fctx->stripe_count); -        else -            dest_offset = frame_offset; - -        STACK_WIND(rframe, stripe_readv_cbk, fctx->xl_array[idx], -                   fctx->xl_array[idx]->fops->readv, fd, frame_size, -                   dest_offset, flags, xdata); - -        frame_offset += frame_size; -    } - -    return 0; -err: -    if (rframe) -        STRIPE_STACK_DESTROY(rframe); - -    STRIPE_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                  struct iatt *postbuf, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    stripe_local_t *mlocal = NULL; -    call_frame_t *prev = NULL; -    call_frame_t *mframe = NULL; -    struct stripe_replies *reply = NULL; -    int32_t i = 0; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; -    mframe = local->orig_frame; -    mlocal = mframe->local; - -    LOCK(&frame->lock); -    { -        callcnt = ++mlocal->call_count; - -        mlocal->replies[local->node_index].op_ret = op_ret; -        mlocal->replies[local->node_index].op_errno = op_errno; - -        if (op_ret >= 0) { -            mlocal->post_buf = *postbuf; -            mlocal->pre_buf = *prebuf; - -            mlocal->prebuf_blocks += prebuf->ia_blocks; -            mlocal->postbuf_blocks += postbuf->ia_blocks; - -            correct_file_size(prebuf, mlocal->fctx, prev); -            correct_file_size(postbuf, mlocal->fctx, prev); - -            if (mlocal->prebuf_size < prebuf->ia_size) -                mlocal->prebuf_size = prebuf->ia_size; -            if (mlocal->postbuf_size < postbuf->ia_size) -                mlocal->postbuf_size = postbuf->ia_size; -        } -    } -    UNLOCK(&frame->lock); - -    if ((callcnt == mlocal->wind_count) && mlocal->unwind) { -        mlocal->pre_buf.ia_size = mlocal->prebuf_size; -        mlocal->pre_buf.ia_blocks = mlocal->prebuf_blocks; -        mlocal->post_buf.ia_size = mlocal->postbuf_size; -        mlocal->post_buf.ia_blocks = mlocal->postbuf_blocks; - -        /* -         * Only return the number of consecutively written bytes up until -         * the first error. Only return an error if it occurs first. -         * -         * When a short write occurs, the application should retry at the -         * appropriate offset, at which point we'll potentially pass back -         * the error. -         */ -        for (i = 0, reply = mlocal->replies; i < mlocal->wind_count; -             i++, reply++) { -            if (reply->op_ret == -1) { -                gf_log(this->name, GF_LOG_DEBUG, -                       "reply %d " -                       "returned error %s", -                       i, strerror(reply->op_errno)); -                if (!mlocal->op_ret) { -                    mlocal->op_ret = -1; -                    mlocal->op_errno = reply->op_errno; -                } -                break; -            } - -            mlocal->op_ret += reply->op_ret; - -            if (reply->op_ret < reply->requested_size) -                break; -        } - -        GF_FREE(mlocal->replies); - -        STRIPE_STACK_UNWIND(writev, mframe, mlocal->op_ret, mlocal->op_errno, -                            &mlocal->pre_buf, &mlocal->post_buf, NULL); -    } -out: -    if (frame) -        STRIPE_STACK_DESTROY(frame); -    return 0; -} - -int32_t -stripe_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, -              struct iovec *vector, int32_t count, off_t offset, uint32_t flags, -              struct iobref *iobref, dict_t *xdata) -{ -    struct iovec *tmp_vec = NULL; -    stripe_local_t *local = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = 1; -    int32_t idx = 0; -    int32_t total_size = 0; -    int32_t offset_offset = 0; -    int32_t remaining_size = 0; -    int32_t tmp_count = count; -    off_t fill_size = 0; -    uint64_t stripe_size = 0; -    uint64_t tmp_fctx = 0; -    off_t dest_offset = 0; -    off_t rounded_start = 0; -    off_t rounded_end = 0; -    int32_t total_chunks = 0; -    call_frame_t *wframe = NULL; -    stripe_local_t *wlocal = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    inode_ctx_get(fd->inode, this, &tmp_fctx); -    if (!tmp_fctx) { -        op_errno = EINVAL; -        goto err; -    } -    fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; -    stripe_size = fctx->stripe_size; - -    STRIPE_VALIDATE_FCTX(fctx, err); - -    /* File has to be stripped across the child nodes */ -    total_size = iov_length(vector, count); -    remaining_size = total_size; - -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    frame->local = local; -    local->stripe_size = stripe_size; -    local->fctx = fctx; - -    if (!stripe_size) { -        gf_log(this->name, GF_LOG_DEBUG, "Wrong stripe size for the file"); -        op_errno = EINVAL; -        goto err; -    } - -    rounded_start = gf_floor(offset, stripe_size); -    rounded_end = gf_roof(offset + total_size, stripe_size); -    total_chunks = (rounded_end - rounded_start) / stripe_size; -    local->replies = GF_CALLOC(total_chunks, sizeof(struct stripe_replies), -                               gf_stripe_mt_stripe_replies); -    if (!local->replies) { -        op_errno = ENOMEM; -        goto err; -    } - -    total_chunks = 0; -    while (1) { -        wframe = copy_frame(frame); -        wlocal = mem_get0(this->local_pool); -        if (!wlocal) { -            op_errno = ENOMEM; -            goto err; -        } -        wlocal->orig_frame = frame; -        wframe->local = wlocal; - -        /* Send striped chunk of the vector to child -           nodes appropriately. */ -        idx = (((offset + offset_offset) / local->stripe_size) % -               fctx->stripe_count); - -        fill_size = (local->stripe_size - -                     ((offset + offset_offset) % local->stripe_size)); -        if (fill_size > remaining_size) -            fill_size = remaining_size; - -        remaining_size -= fill_size; - -        tmp_count = iov_subset(vector, count, offset_offset, -                               offset_offset + fill_size, NULL); -        tmp_vec = GF_CALLOC(tmp_count, sizeof(struct iovec), -                            gf_stripe_mt_iovec); -        if (!tmp_vec) { -            op_errno = ENOMEM; -            goto err; -        } -        tmp_count = iov_subset(vector, count, offset_offset, -                               offset_offset + fill_size, tmp_vec); - -        local->wind_count++; -        if (remaining_size == 0) -            local->unwind = 1; - -        /* -         * Store off the request index (with respect to the chunk of the -         * initial offset) and the size of the request. This is required -         * in the callback to calculate an appropriate return value in -         * the event of a write failure in one or more requests. -         */ -        wlocal->node_index = total_chunks; -        local->replies[total_chunks].requested_size = fill_size; - -        dest_offset = offset + offset_offset; -        if (fctx->stripe_coalesce) -            dest_offset = coalesced_offset(dest_offset, local->stripe_size, -                                           fctx->stripe_count); - -        STACK_WIND(wframe, stripe_writev_cbk, fctx->xl_array[idx], -                   fctx->xl_array[idx]->fops->writev, fd, tmp_vec, tmp_count, -                   dest_offset, flags, iobref, xdata); - -        GF_FREE(tmp_vec); -        offset_offset += fill_size; -        total_chunks++; -        if (remaining_size == 0) -            break; -    } - -    return 0; -err: -    if (wframe) -        STRIPE_STACK_DESTROY(wframe); - -    STRIPE_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                     struct iatt *postbuf, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    stripe_local_t *mlocal = NULL; -    call_frame_t *prev = NULL; -    call_frame_t *mframe = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; -    mframe = local->orig_frame; -    mlocal = mframe->local; - -    LOCK(&frame->lock); -    { -        callcnt = ++mlocal->call_count; - -        if (op_ret == 0) { -            mlocal->post_buf = *postbuf; -            mlocal->pre_buf = *prebuf; - -            mlocal->prebuf_blocks += prebuf->ia_blocks; -            mlocal->postbuf_blocks += postbuf->ia_blocks; - -            correct_file_size(prebuf, mlocal->fctx, prev); -            correct_file_size(postbuf, mlocal->fctx, prev); - -            if (mlocal->prebuf_size < prebuf->ia_size) -                mlocal->prebuf_size = prebuf->ia_size; -            if (mlocal->postbuf_size < postbuf->ia_size) -                mlocal->postbuf_size = postbuf->ia_size; -        } - -        /* return the first failure */ -        if (mlocal->op_ret == 0) { -            mlocal->op_ret = op_ret; -            mlocal->op_errno = op_errno; -        } -    } -    UNLOCK(&frame->lock); - -    if ((callcnt == mlocal->wind_count) && mlocal->unwind) { -        mlocal->pre_buf.ia_size = mlocal->prebuf_size; -        mlocal->pre_buf.ia_blocks = mlocal->prebuf_blocks; -        mlocal->post_buf.ia_size = mlocal->postbuf_size; -        mlocal->post_buf.ia_blocks = mlocal->postbuf_blocks; - -        STRIPE_STACK_UNWIND(fallocate, mframe, mlocal->op_ret, mlocal->op_errno, -                            &mlocal->pre_buf, &mlocal->post_buf, NULL); -    } -out: -    if (frame) -        STRIPE_STACK_DESTROY(frame); -    return 0; -} - -int32_t -stripe_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, -                 off_t offset, size_t len, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = 1; -    int32_t idx = 0; -    int32_t offset_offset = 0; -    int32_t remaining_size = 0; -    off_t fill_size = 0; -    uint64_t stripe_size = 0; -    uint64_t tmp_fctx = 0; -    off_t dest_offset = 0; -    call_frame_t *fframe = NULL; -    stripe_local_t *flocal = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    inode_ctx_get(fd->inode, this, &tmp_fctx); -    if (!tmp_fctx) { -        op_errno = EINVAL; -        goto err; -    } -    fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; -    stripe_size = fctx->stripe_size; - -    STRIPE_VALIDATE_FCTX(fctx, err); - -    remaining_size = len; - -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    frame->local = local; -    local->stripe_size = stripe_size; -    local->fctx = fctx; - -    if (!stripe_size) { -        gf_log(this->name, GF_LOG_DEBUG, "Wrong stripe size for the file"); -        op_errno = EINVAL; -        goto err; -    } - -    while (1) { -        fframe = copy_frame(frame); -        flocal = mem_get0(this->local_pool); -        if (!flocal) { -            op_errno = ENOMEM; -            goto err; -        } -        flocal->orig_frame = frame; -        fframe->local = flocal; - -        /* send fallocate request to the associated child node */ -        idx = (((offset + offset_offset) / local->stripe_size) % -               fctx->stripe_count); - -        fill_size = (local->stripe_size - -                     ((offset + offset_offset) % local->stripe_size)); -        if (fill_size > remaining_size) -            fill_size = remaining_size; - -        remaining_size -= fill_size; - -        local->wind_count++; -        if (remaining_size == 0) -            local->unwind = 1; - -        dest_offset = offset + offset_offset; -        if (fctx->stripe_coalesce) -            dest_offset = coalesced_offset(dest_offset, local->stripe_size, -                                           fctx->stripe_count); - -        /* -         * TODO: Create a separate handler for coalesce mode that sends a -         * single fallocate per-child (since the ranges are linear). -         */ -        STACK_WIND(fframe, stripe_fallocate_cbk, fctx->xl_array[idx], -                   fctx->xl_array[idx]->fops->fallocate, fd, mode, dest_offset, -                   fill_size, xdata); - -        offset_offset += fill_size; -        if (remaining_size == 0) -            break; -    } - -    return 0; -err: -    if (fframe) -        STRIPE_STACK_DESTROY(fframe); - -    STRIPE_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                   struct iatt *postbuf, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    stripe_local_t *mlocal = NULL; -    call_frame_t *prev = NULL; -    call_frame_t *mframe = NULL; - -    if (!this || !frame || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; -    mframe = local->orig_frame; -    mlocal = mframe->local; - -    LOCK(&frame->lock); -    { -        callcnt = ++mlocal->call_count; - -        if (op_ret == 0) { -            mlocal->post_buf = *postbuf; -            mlocal->pre_buf = *prebuf; - -            mlocal->prebuf_blocks += prebuf->ia_blocks; -            mlocal->postbuf_blocks += postbuf->ia_blocks; - -            correct_file_size(prebuf, mlocal->fctx, prev); -            correct_file_size(postbuf, mlocal->fctx, prev); - -            if (mlocal->prebuf_size < prebuf->ia_size) -                mlocal->prebuf_size = prebuf->ia_size; -            if (mlocal->postbuf_size < postbuf->ia_size) -                mlocal->postbuf_size = postbuf->ia_size; -        } - -        /* return the first failure */ -        if (mlocal->op_ret == 0) { -            mlocal->op_ret = op_ret; -            mlocal->op_errno = op_errno; -        } -    } -    UNLOCK(&frame->lock); - -    if ((callcnt == mlocal->wind_count) && mlocal->unwind) { -        mlocal->pre_buf.ia_size = mlocal->prebuf_size; -        mlocal->pre_buf.ia_blocks = mlocal->prebuf_blocks; -        mlocal->post_buf.ia_size = mlocal->postbuf_size; -        mlocal->post_buf.ia_blocks = mlocal->postbuf_blocks; - -        STRIPE_STACK_UNWIND(discard, mframe, mlocal->op_ret, mlocal->op_errno, -                            &mlocal->pre_buf, &mlocal->post_buf, NULL); -    } -out: -    if (frame) -        STRIPE_STACK_DESTROY(frame); - -    return 0; -} - -int32_t -stripe_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -               size_t len, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = 1; -    int32_t idx = 0; -    int32_t offset_offset = 0; -    int32_t remaining_size = 0; -    off_t fill_size = 0; -    uint64_t stripe_size = 0; -    uint64_t tmp_fctx = 0; -    off_t dest_offset = 0; -    call_frame_t *fframe = NULL; -    stripe_local_t *flocal = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    inode_ctx_get(fd->inode, this, &tmp_fctx); -    if (!tmp_fctx) { -        op_errno = EINVAL; -        goto err; -    } -    fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; -    stripe_size = fctx->stripe_size; - -    STRIPE_VALIDATE_FCTX(fctx, err); - -    remaining_size = len; - -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    frame->local = local; -    local->stripe_size = stripe_size; -    local->fctx = fctx; - -    if (!stripe_size) { -        gf_log(this->name, GF_LOG_DEBUG, "Wrong stripe size for the file"); -        op_errno = EINVAL; -        goto err; -    } - -    while (1) { -        fframe = copy_frame(frame); -        flocal = mem_get0(this->local_pool); -        if (!flocal) { -            op_errno = ENOMEM; -            goto err; -        } -        flocal->orig_frame = frame; -        fframe->local = flocal; - -        /* send discard request to the associated child node */ -        idx = (((offset + offset_offset) / local->stripe_size) % -               fctx->stripe_count); - -        fill_size = (local->stripe_size - -                     ((offset + offset_offset) % local->stripe_size)); -        if (fill_size > remaining_size) -            fill_size = remaining_size; - -        remaining_size -= fill_size; - -        local->wind_count++; -        if (remaining_size == 0) -            local->unwind = 1; - -        dest_offset = offset + offset_offset; -        if (fctx->stripe_coalesce) -            dest_offset = coalesced_offset(dest_offset, local->stripe_size, -                                           fctx->stripe_count); - -        /* -         * TODO: Create a separate handler for coalesce mode that sends a -         * single discard per-child (since the ranges are linear). -         */ -        STACK_WIND(fframe, stripe_discard_cbk, fctx->xl_array[idx], -                   fctx->xl_array[idx]->fops->discard, fd, dest_offset, -                   fill_size, xdata); - -        offset_offset += fill_size; -        if (remaining_size == 0) -            break; -    } - -    return 0; -err: -    if (fframe) -        STRIPE_STACK_DESTROY(fframe); - -    STRIPE_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                    struct iatt *postbuf, dict_t *xdata) -{ -    int32_t callcnt = 0; -    stripe_local_t *local = NULL; -    stripe_local_t *mlocal = NULL; -    call_frame_t *prev = NULL; -    call_frame_t *mframe = NULL; - -    GF_ASSERT(frame); - -    if (!this || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } - -    prev = cookie; -    local = frame->local; -    mframe = local->orig_frame; -    mlocal = mframe->local; - -    LOCK(&frame->lock); -    { -        callcnt = ++mlocal->call_count; - -        if (op_ret == 0) { -            mlocal->post_buf = *postbuf; -            mlocal->pre_buf = *prebuf; - -            mlocal->prebuf_blocks += prebuf->ia_blocks; -            mlocal->postbuf_blocks += postbuf->ia_blocks; - -            correct_file_size(prebuf, mlocal->fctx, prev); -            correct_file_size(postbuf, mlocal->fctx, prev); - -            if (mlocal->prebuf_size < prebuf->ia_size) -                mlocal->prebuf_size = prebuf->ia_size; -            if (mlocal->postbuf_size < postbuf->ia_size) -                mlocal->postbuf_size = postbuf->ia_size; -        } - -        /* return the first failure */ -        if (mlocal->op_ret == 0) { -            mlocal->op_ret = op_ret; -            mlocal->op_errno = op_errno; -        } -    } -    UNLOCK(&frame->lock); - -    if ((callcnt == mlocal->wind_count) && mlocal->unwind) { -        mlocal->pre_buf.ia_size = mlocal->prebuf_size; -        mlocal->pre_buf.ia_blocks = mlocal->prebuf_blocks; -        mlocal->post_buf.ia_size = mlocal->postbuf_size; -        mlocal->post_buf.ia_blocks = mlocal->postbuf_blocks; - -        STRIPE_STACK_UNWIND(zerofill, mframe, mlocal->op_ret, mlocal->op_errno, -                            &mlocal->pre_buf, &mlocal->post_buf, NULL); -    } -out: -    STRIPE_STACK_DESTROY(frame); -    return 0; -} - -int32_t -stripe_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -                off_t len, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_fd_ctx_t *fctx = NULL; -    int32_t op_errno = 1; -    int32_t idx = 0; -    int32_t offset_offset = 0; -    int32_t remaining_size = 0; -    off_t fill_size = 0; -    uint64_t stripe_size = 0; -    uint64_t tmp_fctx = 0; -    off_t dest_offset = 0; -    call_frame_t *fframe = NULL; -    stripe_local_t *flocal = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); -    VALIDATE_OR_GOTO(fd->inode, err); - -    inode_ctx_get(fd->inode, this, &tmp_fctx); -    if (!tmp_fctx) { -        op_errno = EINVAL; -        goto err; -    } -    fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; -    stripe_size = fctx->stripe_size; - -    STRIPE_VALIDATE_FCTX(fctx, err); - -    remaining_size = len; - -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    frame->local = local; -    local->stripe_size = stripe_size; -    local->fctx = fctx; - -    if (!stripe_size) { -        gf_log(this->name, GF_LOG_DEBUG, "Wrong stripe size for the file"); -        op_errno = EINVAL; -        goto err; -    } - -    while (1) { -        fframe = copy_frame(frame); -        flocal = mem_get0(this->local_pool); -        if (!flocal) { -            op_errno = ENOMEM; -            goto err; -        } -        flocal->orig_frame = frame; -        fframe->local = flocal; - -        idx = (((offset + offset_offset) / local->stripe_size) % -               fctx->stripe_count); - -        fill_size = (local->stripe_size - -                     ((offset + offset_offset) % local->stripe_size)); -        if (fill_size > remaining_size) -            fill_size = remaining_size; - -        remaining_size -= fill_size; - -        local->wind_count++; -        if (remaining_size == 0) -            local->unwind = 1; - -        dest_offset = offset + offset_offset; -        if (fctx->stripe_coalesce) -            dest_offset = coalesced_offset(dest_offset, local->stripe_size, -                                           fctx->stripe_count); - -        STACK_WIND(fframe, stripe_zerofill_cbk, fctx->xl_array[idx], -                   fctx->xl_array[idx]->fops->zerofill, fd, dest_offset, -                   fill_size, xdata); -        offset_offset += fill_size; -        if (remaining_size == 0) -            break; -    } - -    return 0; -err: -    if (fframe) -        STRIPE_STACK_DESTROY(fframe); - -    STRIPE_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -stripe_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -            gf_seek_what_t what, dict_t *xdata) -{ -    /* TBD */ -    gf_log(this->name, GF_LOG_INFO, "seek called on %s.", -           uuid_utoa(fd->inode->gfid)); -    STRIPE_STACK_UNWIND(seek, frame, -1, ENOTSUP, 0, NULL); -    return 0; -} - -int32_t -stripe_release(xlator_t *this, fd_t *fd) -{ -    return 0; -} - -int -stripe_forget(xlator_t *this, inode_t *inode) -{ -    uint64_t tmp_fctx = 0; -    stripe_fd_ctx_t *fctx = NULL; - -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(inode, err); - -    (void)inode_ctx_del(inode, this, &tmp_fctx); -    if (!tmp_fctx) { -        goto err; -    } - -    fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; - -    if (!fctx->static_array) -        GF_FREE(fctx->xl_array); - -    GF_FREE(fctx); -err: -    return 0; -} - -int32_t -notify(xlator_t *this, int32_t event, void *data, ...) -{ -    stripe_private_t *priv = NULL; -    int down_client = 0; -    int i = 0; -    gf_boolean_t heard_from_all_children = _gf_false; - -    if (!this) -        return 0; - -    priv = this->private; -    if (!priv) -        return 0; - -    switch (event) { -        case GF_EVENT_CHILD_UP: { -            /* get an index number to set */ -            for (i = 0; i < priv->child_count; i++) { -                if (data == priv->xl_array[i]) -                    break; -            } - -            if (priv->child_count == i) { -                gf_log(this->name, GF_LOG_ERROR, -                       "got GF_EVENT_CHILD_UP bad subvolume %s", -                       data ? ((xlator_t *)data)->name : NULL); -                break; -            } - -            LOCK(&priv->lock); -            { -                if (data == FIRST_CHILD(this)) -                    priv->first_child_down = 0; -                priv->last_event[i] = event; -            } -            UNLOCK(&priv->lock); -        } break; -        case GF_EVENT_CHILD_CONNECTING: { -            // 'CONNECTING' doesn't ensure its CHILD_UP, so do nothing -            goto out; -        } -        case GF_EVENT_CHILD_DOWN: { -            /* get an index number to set */ -            for (i = 0; i < priv->child_count; i++) { -                if (data == priv->xl_array[i]) -                    break; -            } - -            if (priv->child_count == i) { -                gf_log(this->name, GF_LOG_ERROR, -                       "got GF_EVENT_CHILD_DOWN bad subvolume %s", -                       data ? ((xlator_t *)data)->name : NULL); -                break; -            } - -            LOCK(&priv->lock); -            { -                if (data == FIRST_CHILD(this)) -                    priv->first_child_down = 1; -                priv->last_event[i] = event; -            } -            UNLOCK(&priv->lock); -        } break; - -        default: { -            /* */ -            default_notify(this, event, data); -            goto out; -        } break; -    } - -    // Consider child as down if it's last_event is not CHILD_UP -    for (i = 0, down_client = 0; i < priv->child_count; i++) -        if (priv->last_event[i] != GF_EVENT_CHILD_UP) -            down_client++; - -    LOCK(&priv->lock); -    { -        priv->nodes_down = down_client; -    } -    UNLOCK(&priv->lock); - -    heard_from_all_children = _gf_true; -    for (i = 0; i < priv->child_count; i++) -        if (!priv->last_event[i]) -            heard_from_all_children = _gf_false; - -    if (heard_from_all_children) -        default_notify(this, event, data); -out: -    return 0; -} - -int -stripe_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int op_ret, int op_errno, dict_t *xdata) -{ -    int ret = -1; -    int call_cnt = 0; -    stripe_local_t *local = NULL; - -    if (!frame || !frame->local || !this) { -        gf_log("", GF_LOG_ERROR, "Possible NULL deref"); -        return ret; -    } - -    local = frame->local; - -    LOCK(&frame->lock); -    { -        call_cnt = --local->wind_count; - -        /** -         * We overwrite ->op_* values here for subsequent failure -         * conditions, hence we propagate the last errno down the -         * stack. -         */ -        if (op_ret < 0) { -            local->op_ret = op_ret; -            local->op_errno = op_errno; -            goto unlock; -        } -    } - -unlock: -    UNLOCK(&frame->lock); - -    if (!call_cnt) { -        STRIPE_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, -                            xdata); -    } - -    return 0; -} - -#ifdef HAVE_BD_XLATOR -int -stripe_is_bd(dict_t *this, char *key, data_t *value, void *data) -{ -    gf_boolean_t *is_bd = data; - -    if (data == NULL) -        return 0; - -    if (XATTR_IS_BD(key)) -        *is_bd = _gf_true; - -    return 0; -} - -static gf_boolean_t -stripe_setxattr_is_bd(dict_t *dict) -{ -    gf_boolean_t is_bd = _gf_false; - -    if (dict == NULL) -        goto out; - -    dict_foreach(dict, stripe_is_bd, &is_bd); -out: -    return is_bd; -} -#else -#define stripe_setxattr_is_bd(dict) _gf_false -#endif - -int -stripe_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, -                int flags, dict_t *xdata) -{ -    int32_t op_errno = EINVAL; -    xlator_list_t *trav = NULL; -    stripe_private_t *priv = NULL; -    stripe_local_t *local = NULL; -    int i = 0; -    gf_boolean_t is_bd = _gf_false; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    GF_IF_INTERNAL_XATTR_GOTO("trusted.*stripe*", dict, op_errno, err); - -    priv = this->private; -    trav = this->children; - -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    frame->local = local; -    local->wind_count = priv->child_count; -    local->op_ret = local->op_errno = 0; - -    is_bd = stripe_setxattr_is_bd(dict); - -    /** -     * Set xattrs for directories on all subvolumes. Additionally -     * this power is only given to a special client. Bd xlator -     * also needs xattrs for regular files (ie LVs) -     */ -    if (((frame->root->pid == GF_CLIENT_PID_GSYNCD) && -         IA_ISDIR(loc->inode->ia_type)) || -        is_bd) { -        for (i = 0; i < priv->child_count; i++, trav = trav->next) { -            STACK_WIND(frame, stripe_setxattr_cbk, trav->xlator, -                       trav->xlator->fops->setxattr, loc, dict, flags, xdata); -        } -    } else { -        local->wind_count = 1; -        STACK_WIND(frame, stripe_setxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); -    } - -    return 0; -err: -    STRIPE_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); -    return 0; -} - -int -stripe_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int op_ret, int op_errno, dict_t *xdata) -{ -    STRIPE_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int -stripe_is_special_key(dict_t *this, char *key, data_t *value, void *data) -{ -    gf_boolean_t *is_special = NULL; - -    if (data == NULL) { -        goto out; -    } - -    is_special = data; - -    if (XATTR_IS_LOCKINFO(key) || XATTR_IS_BD(key)) -        *is_special = _gf_true; - -out: -    return 0; -} - -int32_t -stripe_fsetxattr_everyone_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                              int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    int call_count = 0; -    stripe_local_t *local = NULL; - -    local = frame->local; - -    LOCK(&frame->lock); -    { -        call_count = --local->wind_count; - -        if (op_ret < 0) { -            local->op_ret = op_ret; -            local->op_errno = op_errno; -        } -    } -    UNLOCK(&frame->lock); - -    if (call_count == 0) { -        STRIPE_STACK_UNWIND(fsetxattr, frame, local->op_ret, local->op_errno, -                            NULL); -    } -    return 0; -} - -int -stripe_fsetxattr_to_everyone(call_frame_t *frame, xlator_t *this, fd_t *fd, -                             dict_t *dict, int flags, dict_t *xdata) -{ -    xlator_list_t *trav = NULL; -    stripe_private_t *priv = NULL; -    int ret = -1; -    stripe_local_t *local = NULL; - -    priv = this->private; - -    local = mem_get0(this->local_pool); -    if (local == NULL) { -        goto out; -    } - -    frame->local = local; - -    local->wind_count = priv->child_count; - -    trav = this->children; - -    while (trav) { -        STACK_WIND(frame, stripe_fsetxattr_everyone_cbk, trav->xlator, -                   trav->xlator->fops->fsetxattr, fd, dict, flags, xdata); -        trav = trav->next; -    } - -    ret = 0; -out: -    return ret; -} - -static gf_boolean_t -stripe_fsetxattr_is_special(dict_t *dict) -{ -    gf_boolean_t is_spl = _gf_false; - -    if (dict == NULL) { -        goto out; -    } - -    dict_foreach(dict, stripe_is_special_key, &is_spl); - -out: -    return is_spl; -} - -int -stripe_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, -                 int flags, dict_t *xdata) -{ -    int32_t op_ret = -1, ret = -1, op_errno = EINVAL; -    gf_boolean_t is_spl = _gf_false; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); - -    GF_IF_INTERNAL_XATTR_GOTO("trusted.*stripe*", dict, op_errno, err); - -    is_spl = stripe_fsetxattr_is_special(dict); -    if (is_spl) { -        ret = stripe_fsetxattr_to_everyone(frame, this, fd, dict, flags, xdata); -        if (ret < 0) { -            op_errno = ENOMEM; -            goto err; -        } - -        goto out; -    } - -    STACK_WIND(frame, stripe_fsetxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); -out: -    return 0; -err: -    STRIPE_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, NULL); -    return 0; -} - -int -stripe_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    STRIPE_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int -stripe_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, -                   const char *name, dict_t *xdata) -{ -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(this, err); - -    GF_IF_NATIVE_XATTR_GOTO("trusted.*stripe*", name, op_errno, err); - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(loc, err); - -    STACK_WIND(frame, stripe_removexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); -    return 0; -err: -    STRIPE_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); -    return 0; -} - -int -stripe_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    STRIPE_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int -stripe_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, -                    const char *name, dict_t *xdata) -{ -    int32_t op_ret = -1; -    int32_t op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); - -    GF_IF_NATIVE_XATTR_GOTO("trusted.*stripe*", name, op_errno, err); - -    STACK_WIND(frame, stripe_fremovexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); -    return 0; -err: -    STRIPE_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int32_t -stripe_readdirp_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) -{ -    stripe_local_t *local = NULL; -    call_frame_t *main_frame = NULL; -    stripe_local_t *main_local = NULL; -    gf_dirent_t *entry = NULL; -    call_frame_t *prev = NULL; -    int done = 0; - -    local = frame->local; -    prev = cookie; - -    entry = local->dirent; - -    main_frame = local->orig_frame; -    main_local = main_frame->local; -    LOCK(&frame->lock); -    { -        local->call_count--; -        if (!local->call_count) -            done = 1; -        if (op_ret == -1) { -            local->op_errno = op_errno; -            local->op_ret = op_ret; -            goto unlock; -        } - -        if (stripe_ctx_handle(this, prev, local, xattr)) -            gf_log(this->name, GF_LOG_ERROR, -                   "Error getting fctx info from dict."); - -        correct_file_size(stbuf, local->fctx, prev); - -        stripe_iatt_merge(stbuf, &entry->d_stat); -        local->stbuf_blocks += stbuf->ia_blocks; -    } -unlock: -    UNLOCK(&frame->lock); - -    if (done) { -        inode_ctx_put(entry->inode, this, (uint64_t)(long)local->fctx); - -        done = 0; -        LOCK(&main_frame->lock); -        { -            main_local->wind_count--; -            if (!main_local->wind_count) -                done = 1; -            if (local->op_ret == -1) { -                main_local->op_errno = local->op_errno; -                main_local->op_ret = local->op_ret; -            } -            entry->d_stat.ia_blocks = local->stbuf_blocks; -        } -        UNLOCK(&main_frame->lock); -        if (done) { -            main_frame->local = NULL; -            STRIPE_STACK_UNWIND(readdir, main_frame, main_local->op_ret, -                                main_local->op_errno, &main_local->entries, -                                NULL); -            gf_dirent_free(&main_local->entries); -            stripe_local_wipe(main_local); -            mem_put(main_local); -        } -        frame->local = NULL; -        stripe_local_wipe(local); -        mem_put(local); -        STRIPE_STACK_DESTROY(frame); -    } - -    return 0; -} - -int32_t -stripe_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, gf_dirent_t *orig_entries, -                    dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    call_frame_t *prev = NULL; -    gf_dirent_t *local_entry = NULL; -    gf_dirent_t *tmp_entry = NULL; -    xlator_list_t *trav = NULL; -    loc_t loc = { -        0, -    }; -    int32_t count = 0; -    stripe_private_t *priv = NULL; -    int32_t subvols = 0; -    dict_t *xattrs = NULL; -    call_frame_t *local_frame = NULL; -    stripe_local_t *local_ent = NULL; - -    if (!this || !frame->local || !cookie) { -        gf_log("stripe", GF_LOG_DEBUG, "possible NULL deref"); -        goto out; -    } -    prev = cookie; -    local = frame->local; -    trav = this->children; -    priv = this->private; - -    subvols = priv->child_count; - -    LOCK(&frame->lock); -    { -        local->op_errno = op_errno; -        local->op_ret = op_ret; - -        if (op_ret != -1) { -            list_splice_init(&orig_entries->list, &local->entries.list); -            local->wind_count = op_ret; -        } -    } -    UNLOCK(&frame->lock); - -    if (op_ret == -1) { -        gf_log(this->name, GF_LOG_WARNING, "%s returned error %s", -               prev->this->name, strerror(op_errno)); -        goto out; -    } - -    xattrs = dict_new(); -    if (xattrs) -        (void)stripe_xattr_request_build(this, xattrs, 0, 0, 0, 0); -    count = op_ret; -    list_for_each_entry_safe(local_entry, tmp_entry, (&local->entries.list), -                             list) -    { -        if (!local_entry) -            break; -        if (!IA_ISREG(local_entry->d_stat.ia_type) || !local_entry->inode) { -            LOCK(&frame->lock); -            { -                local->wind_count--; -                count = local->wind_count; -            } -            UNLOCK(&frame->lock); -            continue; -        } - -        local_frame = copy_frame(frame); - -        if (!local_frame) { -            op_errno = ENOMEM; -            op_ret = -1; -            goto out; -        } - -        local_ent = mem_get0(this->local_pool); -        if (!local_ent) { -            op_errno = ENOMEM; -            op_ret = -1; -            goto out; -        } - -        loc.inode = inode_ref(local_entry->inode); - -        gf_uuid_copy(loc.gfid, local_entry->d_stat.ia_gfid); - -        local_ent->orig_frame = frame; - -        local_ent->call_count = subvols; - -        local_ent->dirent = local_entry; - -        local_frame->local = local_ent; - -        trav = this->children; -        while (trav) { -            STACK_WIND(local_frame, stripe_readdirp_lookup_cbk, trav->xlator, -                       trav->xlator->fops->lookup, &loc, xattrs); -            trav = trav->next; -        } -        loc_wipe(&loc); -    } -out: -    if (!count) { -        /* all entries are directories */ -        frame->local = NULL; -        STRIPE_STACK_UNWIND(readdir, frame, (local ? local->op_ret : -1), -                            (local ? local->op_errno : EINVAL), -                            (local ? &local->entries : NULL), NULL); -        gf_dirent_free(&local->entries); -        stripe_local_wipe(local); -        mem_put(local); -    } -    if (xattrs) -        dict_unref(xattrs); -    return 0; -} -int32_t -stripe_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -                off_t off, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    xlator_list_t *trav = NULL; -    int op_errno = -1; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); - -    priv = this->private; -    trav = this->children; - -    if (priv->first_child_down) { -        op_errno = ENOTCONN; -        goto err; -    } - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    frame->local = local; - -    local->fd = fd_ref(fd); - -    local->wind_count = 0; - -    local->count = 0; -    local->op_ret = -1; -    INIT_LIST_HEAD(&local->entries); - -    if (!trav) -        goto err; - -    STACK_WIND(frame, stripe_readdirp_cbk, trav->xlator, -               trav->xlator->fops->readdirp, fd, size, off, xdata); -    return 0; -err: -    op_errno = (op_errno == -1) ? errno : op_errno; -    STRIPE_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); - -    return 0; -} - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    if (!this) -        goto out; - -    ret = xlator_mem_acct_init(this, gf_stripe_mt_end + 1); - -    if (ret != 0) { -        gf_log(this->name, GF_LOG_ERROR, -               "Memory accounting init" -               "failed"); -        goto out; -    } - -out: -    return ret; -} - -static int -clear_pattern_list(stripe_private_t *priv) -{ -    struct stripe_options *prev = NULL; -    struct stripe_options *trav = NULL; -    int ret = -1; - -    GF_VALIDATE_OR_GOTO("stripe", priv, out); - -    trav = priv->pattern; -    priv->pattern = NULL; -    while (trav) { -        prev = trav; -        trav = trav->next; -        GF_FREE(prev); -    } - -    ret = 0; -out: -    return ret; -} - -int -reconfigure(xlator_t *this, dict_t *options) -{ -    stripe_private_t *priv = NULL; -    data_t *data = NULL; -    int ret = -1; -    volume_option_t *opt = NULL; - -    GF_ASSERT(this); -    GF_ASSERT(this->private); - -    priv = this->private; - -    ret = 0; -    LOCK(&priv->lock); -    { -        ret = clear_pattern_list(priv); -        if (ret) -            goto unlock; - -        data = dict_get(options, "block-size"); -        if (data) { -            ret = set_stripe_block_size(this, priv, data->data); -            if (ret) -                goto unlock; -        } else { -            opt = xlator_volume_option_get(this, "block-size"); -            if (!opt) { -                gf_log(this->name, GF_LOG_WARNING, -                       "option 'block-size' not found"); -                ret = -1; -                goto unlock; -            } - -            if (gf_string2bytesize_uint64(opt->default_value, -                                          &priv->block_size)) { -                gf_log(this->name, GF_LOG_ERROR, -                       "Unable to set default block-size "); -                ret = -1; -                goto unlock; -            } -        } - -        GF_OPTION_RECONF("coalesce", priv->coalesce, options, bool, unlock); -    } -unlock: -    UNLOCK(&priv->lock); -    if (ret) -        goto out; - -    ret = 0; -out: -    return ret; -} - -/** - * init - This function is called when xlator-graph gets initialized. - *     The option given in volfiles are parsed here. - * @this - - */ -int32_t -init(xlator_t *this) -{ -    stripe_private_t *priv = NULL; -    volume_option_t *opt = NULL; -    xlator_list_t *trav = NULL; -    data_t *data = NULL; -    int32_t count = 0; -    int ret = -1; - -    if (!this) -        goto out; - -    trav = this->children; -    while (trav) { -        count++; -        trav = trav->next; -    } - -    if (!count) { -        gf_log(this->name, GF_LOG_ERROR, -               "stripe configured without \"subvolumes\" option. " -               "exiting"); -        goto out; -    } - -    if (!this->parents) { -        gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); -    } - -    if (count == 1) { -        gf_log(this->name, GF_LOG_ERROR, -               "stripe configured with only one \"subvolumes\" option." -               " please check the volume. exiting"); -        goto out; -    } - -    priv = GF_CALLOC(1, sizeof(stripe_private_t), -                     gf_stripe_mt_stripe_private_t); - -    if (!priv) -        goto out; -    priv->xl_array = GF_CALLOC(count, sizeof(xlator_t *), -                               gf_stripe_mt_xlator_t); -    if (!priv->xl_array) -        goto out; - -    priv->last_event = GF_CALLOC(count, sizeof(int), gf_stripe_mt_int32_t); -    if (!priv->last_event) -        goto out; - -    priv->child_count = count; -    LOCK_INIT(&priv->lock); - -    trav = this->children; -    count = 0; -    while (trav) { -        priv->xl_array[count++] = trav->xlator; -        trav = trav->next; -    } - -    if (count > 256) { -        gf_log(this->name, GF_LOG_ERROR, -               "maximum number of stripe subvolumes supported " -               "is 256"); -        goto out; -    } - -    ret = 0; -    LOCK(&priv->lock); -    { -        opt = xlator_volume_option_get(this, "block-size"); -        if (!opt) { -            gf_log(this->name, GF_LOG_WARNING, "option 'block-size' not found"); -            ret = -1; -            goto unlock; -        } -        if (gf_string2bytesize_uint64(opt->default_value, &priv->block_size)) { -            gf_log(this->name, GF_LOG_ERROR, -                   "Unable to set default block-size "); -            ret = -1; -            goto unlock; -        } -        /* option stripe-pattern *avi:1GB,*pdf:16K */ -        data = dict_get(this->options, "block-size"); -        if (data) { -            ret = set_stripe_block_size(this, priv, data->data); -            if (ret) -                goto unlock; -        } -    } -unlock: -    UNLOCK(&priv->lock); -    if (ret) -        goto out; - -    GF_OPTION_INIT("use-xattr", priv->xattr_supported, bool, out); -    /* notify related */ -    priv->nodes_down = priv->child_count; - -    GF_OPTION_INIT("coalesce", priv->coalesce, bool, out); - -    this->local_pool = mem_pool_new(stripe_local_t, 128); -    if (!this->local_pool) { -        ret = -1; -        gf_log(this->name, GF_LOG_ERROR, -               "failed to create local_t's memory pool"); -        goto out; -    } - -    this->private = priv; - -    ret = 0; -out: -    if (ret) { -        if (priv) { -            GF_FREE(priv->xl_array); -            GF_FREE(priv); -        } -    } -    return ret; -} - -/** - * fini -   Free all the private variables - * @this - - */ -void -fini(xlator_t *this) -{ -    stripe_private_t *priv = NULL; -    struct stripe_options *prev = NULL; -    struct stripe_options *trav = NULL; - -    if (!this) -        goto out; - -    priv = this->private; -    if (priv) { -        this->private = NULL; -        GF_FREE(priv->xl_array); - -        trav = priv->pattern; -        while (trav) { -            prev = trav; -            trav = trav->next; -            GF_FREE(prev); -        } -        GF_FREE(priv->last_event); -        LOCK_DESTROY(&priv->lock); -        GF_FREE(priv); -    } - -out: -    return; -} - -int32_t -stripe_getxattr_unwind(call_frame_t *frame, int op_ret, int op_errno, -                       dict_t *dict, dict_t *xdata) - -{ -    STRIPE_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); -    return 0; -} - -int -stripe_internal_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                             int op_ret, int op_errno, dict_t *xattr, -                             dict_t *xdata) -{ -    char size_key[256] = { -        0, -    }; -    char index_key[256] = { -        0, -    }; -    char count_key[256] = { -        0, -    }; -    char coalesce_key[256] = { -        0, -    }; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(frame->local, out); - -    if (!xattr || (op_ret == -1)) -        goto out; - -    sprintf(size_key, "trusted.%s.stripe-size", this->name); -    sprintf(count_key, "trusted.%s.stripe-count", this->name); -    sprintf(index_key, "trusted.%s.stripe-index", this->name); -    sprintf(coalesce_key, "trusted.%s.stripe-coalesce", this->name); - -    dict_del(xattr, size_key); -    dict_del(xattr, count_key); -    dict_del(xattr, index_key); -    dict_del(xattr, coalesce_key); - -out: -    STRIPE_STACK_UNWIND(getxattr, frame, op_ret, op_errno, xattr, xdata); - -    return 0; -} - -int -stripe_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) -{ -    int call_cnt = 0; -    stripe_local_t *local = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(frame->local, out); - -    local = frame->local; - -    LOCK(&frame->lock); -    { -        call_cnt = --local->wind_count; -    } -    UNLOCK(&frame->lock); - -    if (!xattr || (op_ret < 0)) -        goto out; - -    local->op_ret = 0; - -    if (!local->xattr) { -        local->xattr = dict_ref(xattr); -    } else { -        stripe_aggregate_xattr(local->xattr, xattr); -    } - -out: -    if (!call_cnt) { -        STRIPE_STACK_UNWIND(getxattr, frame, (local ? local->op_ret : -1), -                            op_errno, (local ? local->xattr : NULL), xdata); -    } - -    return 0; -} - -int32_t -stripe_vgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, dict_t *dict, -                     dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    int32_t callcnt = 0; -    int32_t ret = -1; -    long cky = 0; -    void *xattr_val = NULL; -    void *xattr_serz = NULL; -    stripe_xattr_sort_t *xattr = NULL; -    dict_t *stripe_xattr = NULL; - -    if (!frame || !frame->local || !this) { -        gf_log("", GF_LOG_ERROR, "Possible NULL deref"); -        return ret; -    } - -    local = frame->local; -    cky = (long)cookie; - -    if (local->xsel[0] == '\0') { -        gf_log(this->name, GF_LOG_ERROR, "Empty xattr in cbk"); -        return ret; -    } - -    LOCK(&frame->lock); -    { -        callcnt = --local->wind_count; - -        if (!dict || (op_ret < 0)) -            goto out; - -        if (!local->xattr_list) -            local->xattr_list = (stripe_xattr_sort_t *)GF_CALLOC( -                local->nallocs, sizeof(stripe_xattr_sort_t), -                gf_stripe_mt_xattr_sort_t); - -        if (local->xattr_list) { -            xattr = local->xattr_list + (int32_t)cky; - -            ret = dict_get_ptr_and_len(dict, local->xsel, &xattr_val, -                                       &xattr->xattr_len); -            if (xattr->xattr_len == 0) -                goto out; - -            xattr->pos = cky; -            xattr->xattr_value = gf_memdup(xattr_val, xattr->xattr_len); - -            if (xattr->xattr_value != NULL) -                local->xattr_total_len += xattr->xattr_len + 1; -        } -    } -out: -    UNLOCK(&frame->lock); - -    if (!callcnt) { -        if (!local->xattr_total_len) -            goto unwind; - -        stripe_xattr = dict_new(); -        if (!stripe_xattr) -            goto unwind; - -        /* select filler based on ->xsel */ -        if (XATTR_IS_PATHINFO(local->xsel)) -            ret = stripe_fill_pathinfo_xattr(this, local, (char **)&xattr_serz); -        else if (XATTR_IS_LOCKINFO(local->xsel)) { -            ret = stripe_fill_lockinfo_xattr(this, local, &xattr_serz); -        } else { -            gf_log(this->name, GF_LOG_WARNING, -                   "Unknown xattr in xattr request"); -            goto unwind; -        } - -        if (!ret) { -            ret = dict_set_dynptr(stripe_xattr, local->xsel, xattr_serz, -                                  local->xattr_total_len); -            if (ret) -                gf_log(this->name, GF_LOG_ERROR, "Can't set %s key in dict", -                       local->xsel); -        } - -    unwind: -        /* -         * Among other things, STRIPE_STACK_UNWIND will free "local" -         * for us.  That means we can't dereference it afterward. -         * Fortunately, the actual result is in stripe_xattr now, so we -         * can simply clean up before unwinding. -         */ -        ret = stripe_free_xattr_str(local); -        GF_FREE(local->xattr_list); -        local->xattr_list = NULL; - -        STRIPE_STACK_UNWIND(getxattr, frame, op_ret, op_errno, stripe_xattr, -                            NULL); - -        if (stripe_xattr) -            dict_unref(stripe_xattr); -    } - -    return ret; -} - -int -stripe_marker_populate_args(call_frame_t *frame, int type, int *gauge, -                            xlator_t **subvols) -{ -    xlator_t *this = frame->this; -    stripe_private_t *priv = this->private; -    stripe_local_t *local = frame->local; -    int count = 0; - -    count = priv->child_count; -    if (MARKER_XTIME_TYPE == type) { -        if (!IA_FILE_OR_DIR(local->loc.inode->ia_type)) -            count = 1; -    } -    memcpy(subvols, priv->xl_array, sizeof(*subvols) * count); - -    return count; -} - -int32_t -stripe_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, -                const char *name, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    xlator_list_t *trav = NULL; -    stripe_private_t *priv = NULL; -    int32_t op_errno = EINVAL; -    int i = 0; -    int ret = 0; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(loc, err); -    VALIDATE_OR_GOTO(loc->path, err); -    VALIDATE_OR_GOTO(loc->inode, err); - -    priv = this->private; -    trav = this->children; - -    /* Initialization */ -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } -    local->op_ret = -1; -    frame->local = local; -    loc_copy(&local->loc, loc); - -    if (name && strncmp(name, QUOTA_SIZE_KEY, SLEN(QUOTA_SIZE_KEY)) == 0) { -        local->wind_count = priv->child_count; - -        for (i = 0, trav = this->children; i < priv->child_count; -             i++, trav = trav->next) { -            STACK_WIND(frame, stripe_getxattr_cbk, trav->xlator, -                       trav->xlator->fops->getxattr, loc, name, xdata); -        } - -        return 0; -    } - -    if (name && (XATTR_IS_PATHINFO(name))) { -        if (IA_ISREG(loc->inode->ia_type)) { -            ret = inode_ctx_get(loc->inode, this, (uint64_t *)&local->fctx); -            if (ret) -                gf_log(this->name, GF_LOG_ERROR, -                       "stripe size unavailable from fctx" -                       " relying on pathinfo could lead to" -                       " wrong results"); -        } - -        local->nallocs = local->wind_count = priv->child_count; -        (void)strncpy(local->xsel, name, strlen(name)); - -        /** -         * for xattrs that need info from all children, fill ->xsel -         * as above and call the filler function in cbk based on -         * it -         */ -        for (i = 0, trav = this->children; i < priv->child_count; -             i++, trav = trav->next) { -            STACK_WIND_COOKIE(frame, stripe_vgetxattr_cbk, (void *)(long)i, -                              trav->xlator, trav->xlator->fops->getxattr, loc, -                              name, xdata); -        } - -        return 0; -    } - -    if (cluster_handle_marker_getxattr(frame, loc, name, priv->vol_uuid, -                                       stripe_getxattr_unwind, -                                       stripe_marker_populate_args) == 0) -        return 0; - -    STACK_WIND(frame, stripe_internal_getxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); - -    return 0; - -err: -    STRIPE_STACK_UNWIND(getxattr, frame, -1, op_errno, NULL, NULL); -    return 0; -} - -static gf_boolean_t -stripe_is_special_xattr(const char *name) -{ -    gf_boolean_t is_spl = _gf_false; - -    if (!name) { -        goto out; -    } - -    if (!strncmp(name, GF_XATTR_LOCKINFO_KEY, SLEN(GF_XATTR_LOCKINFO_KEY)) || -        XATTR_IS_PATHINFO(name)) -        is_spl = _gf_true; -out: -    return is_spl; -} - -int32_t -stripe_fgetxattr_from_everyone(call_frame_t *frame, xlator_t *this, fd_t *fd, -                               const char *name, dict_t *xdata) -{ -    stripe_local_t *local = NULL; -    stripe_private_t *priv = NULL; -    int32_t ret = -1, op_errno = 0; -    int i = 0; -    xlator_list_t *trav = NULL; - -    priv = this->private; - -    local = mem_get0(this->local_pool); -    if (!local) { -        op_errno = ENOMEM; -        goto err; -    } - -    local->op_ret = -1; -    frame->local = local; - -    strncpy(local->xsel, name, strlen(name)); -    local->nallocs = local->wind_count = priv->child_count; - -    for (i = 0, trav = this->children; i < priv->child_count; -         i++, trav = trav->next) { -        STACK_WIND_COOKIE(frame, stripe_vgetxattr_cbk, (void *)(long)i, -                          trav->xlator, trav->xlator->fops->fgetxattr, fd, name, -                          xdata); -    } - -    return 0; - -err: -    STACK_UNWIND_STRICT(fgetxattr, frame, -1, op_errno, NULL, NULL); -    return ret; -} - -int32_t -stripe_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, -                 const char *name, dict_t *xdata) -{ -    if (stripe_is_special_xattr(name)) { -        stripe_fgetxattr_from_everyone(frame, this, fd, name, xdata); -        goto out; -    } - -    STACK_WIND(frame, stripe_internal_getxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); - -out: -    return 0; -} - -int32_t -stripe_priv_dump(xlator_t *this) -{ -    char key[GF_DUMP_MAX_BUF_LEN]; -    int i = 0; -    stripe_private_t *priv = NULL; -    int ret = -1; -    struct stripe_options *options = NULL; - -    GF_VALIDATE_OR_GOTO("stripe", this, out); - -    priv = this->private; -    if (!priv) -        goto out; - -    ret = TRY_LOCK(&priv->lock); -    if (ret != 0) -        goto out; - -    gf_proc_dump_add_section("xlator.cluster.stripe.%s.priv", this->name); -    gf_proc_dump_write("child_count", "%d", priv->child_count); - -    for (i = 0; i < priv->child_count; i++) { -        sprintf(key, "subvolumes[%d]", i); -        gf_proc_dump_write(key, "%s.%s", priv->xl_array[i]->type, -                           priv->xl_array[i]->name); -    } - -    options = priv->pattern; -    while (options != NULL) { -        gf_proc_dump_write("path_pattern", "%s", priv->pattern->path_pattern); -        gf_proc_dump_write("options_block_size", "%ul", options->block_size); - -        options = options->next; -    } - -    gf_proc_dump_write("block_size", "%ul", priv->block_size); -    gf_proc_dump_write("nodes-down", "%d", priv->nodes_down); -    gf_proc_dump_write("first-child_down", "%d", priv->first_child_down); -    gf_proc_dump_write("xattr_supported", "%d", priv->xattr_supported); - -    UNLOCK(&priv->lock); - -out: -    return ret; -} - -struct xlator_fops fops = { -    .stat = stripe_stat, -    .unlink = stripe_unlink, -    .rename = stripe_rename, -    .link = stripe_link, -    .truncate = stripe_truncate, -    .create = stripe_create, -    .open = stripe_open, -    .readv = stripe_readv, -    .writev = stripe_writev, -    .statfs = stripe_statfs, -    .flush = stripe_flush, -    .fsync = stripe_fsync, -    .ftruncate = stripe_ftruncate, -    .fstat = stripe_fstat, -    .mkdir = stripe_mkdir, -    .rmdir = stripe_rmdir, -    .lk = stripe_lk, -    .opendir = stripe_opendir, -    .fsyncdir = stripe_fsyncdir, -    .setattr = stripe_setattr, -    .fsetattr = stripe_fsetattr, -    .lookup = stripe_lookup, -    .mknod = stripe_mknod, -    .setxattr = stripe_setxattr, -    .fsetxattr = stripe_fsetxattr, -    .getxattr = stripe_getxattr, -    .fgetxattr = stripe_fgetxattr, -    .removexattr = stripe_removexattr, -    .fremovexattr = stripe_fremovexattr, -    .readdirp = stripe_readdirp, -    .fallocate = stripe_fallocate, -    .discard = stripe_discard, -    .zerofill = stripe_zerofill, -    .seek = stripe_seek, -}; - -struct xlator_cbks cbks = { -    .release = stripe_release, -    .forget = stripe_forget, -}; - -struct xlator_dumpops dumpops = { -    .priv = stripe_priv_dump, -}; - -struct volume_options options[] = { -    { -        .key = {"block-size"}, -        .type = GF_OPTION_TYPE_SIZE_LIST, -        .default_value = "128KB", -        .min = STRIPE_MIN_BLOCK_SIZE, -        .description = "Size of the stripe unit that would be read " -                       "from or written to the striped servers.", -        .op_version = {1}, -        .tags = {"stripe"}, -        .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE, -    }, -    { -        .key = {"use-xattr"}, -        .type = GF_OPTION_TYPE_BOOL, -        .default_value = "true", -        .description = "handle the stripe without the xattr", -        .tags = {"stripe", "dev-only"}, -        .flags = OPT_FLAG_CLIENT_OPT, -    }, -    { -        .key = {"coalesce"}, -        .type = GF_OPTION_TYPE_BOOL, -        .default_value = "true", -        .description = "Enable/Disable coalesce mode to flatten striped " -                       "files as stored on the server (i.e., eliminate holes " -                       "caused by the traditional format).", -        .op_version = {1}, -        .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE, -        .tags = {"stripe"}, -    }, -    {.key = {NULL}}, -}; diff --git a/xlators/cluster/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h deleted file mode 100644 index 88c24b682b8..00000000000 --- a/xlators/cluster/stripe/src/stripe.h +++ /dev/null @@ -1,291 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _STRIPE_H_ -#define _STRIPE_H_ - -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/defaults.h> -#include <glusterfs/common-utils.h> -#include <glusterfs/compat.h> -#include <glusterfs/compat-errno.h> -#include "stripe-mem-types.h" -#include "libxlator.h" -#include <fnmatch.h> -#include <signal.h> - -#define STRIPE_PATHINFO_HEADER "STRIPE:" -#define STRIPE_MIN_BLOCK_SIZE (16 * GF_UNIT_KB) - -#define STRIPE_STACK_UNWIND(fop, frame, params...)                             \ -    do {                                                                       \ -        stripe_local_t *__local = NULL;                                        \ -        if (frame) {                                                           \ -            __local = frame->local;                                            \ -            frame->local = NULL;                                               \ -        }                                                                      \ -        STACK_UNWIND_STRICT(fop, frame, params);                               \ -        if (__local) {                                                         \ -            stripe_local_wipe(__local);                                        \ -            mem_put(__local);                                                  \ -        }                                                                      \ -    } while (0) - -#define STRIPE_STACK_DESTROY(frame)                                            \ -    do {                                                                       \ -        stripe_local_t *__local = NULL;                                        \ -        __local = frame->local;                                                \ -        frame->local = NULL;                                                   \ -        STACK_DESTROY(frame->root);                                            \ -        if (__local) {                                                         \ -            stripe_local_wipe(__local);                                        \ -            mem_put(__local);                                                  \ -        }                                                                      \ -    } while (0) - -#define STRIPE_VALIDATE_FCTX(fctx, label)                                      \ -    do {                                                                       \ -        int idx = 0;                                                           \ -        if (!fctx) {                                                           \ -            op_errno = EINVAL;                                                 \ -            goto label;                                                        \ -        }                                                                      \ -        for (idx = 0; idx < fctx->stripe_count; idx++) {                       \ -            if (!fctx->xl_array[idx]) {                                        \ -                gf_log(this->name, GF_LOG_ERROR, "fctx->xl_array[%d] is NULL", \ -                       idx);                                                   \ -                op_errno = ESTALE;                                             \ -                goto label;                                                    \ -            }                                                                  \ -        }                                                                      \ -    } while (0) - -typedef struct stripe_xattr_sort { -    int pos; -    int xattr_len; -    char *xattr_value; -} stripe_xattr_sort_t; - -/** - * struct stripe_options : This keeps the pattern and the block-size - *     information, which is used for striping on a file. - */ -struct stripe_options { -    struct stripe_options *next; -    char path_pattern[256]; -    uint64_t block_size; -}; - -/** - * Private structure for stripe translator - */ -struct stripe_private { -    struct stripe_options *pattern; -    xlator_t **xl_array; -    uint64_t block_size; -    gf_lock_t lock; -    uint8_t nodes_down; -    int8_t first_child_down; -    int *last_event; -    int8_t child_count; -    gf_boolean_t xattr_supported; /* default yes */ -    gf_boolean_t coalesce; -    char vol_uuid[UUID_SIZE + 1]; -}; - -/** - * Used to keep info about the replies received from readv/writev calls - */ -struct stripe_replies { -    struct iovec *vector; -    int32_t count;   // count of vector -    int32_t op_ret;  // op_ret of readv -    int32_t op_errno; -    int32_t requested_size; -    struct iatt stbuf; /* 'stbuf' is also a part of reply */ -}; - -typedef struct _stripe_fd_ctx { -    off_t stripe_size; -    int stripe_count; -    int stripe_coalesce; -    int static_array; -    xlator_t **xl_array; -} stripe_fd_ctx_t; - -/** - * Local structure to be passed with all the frames in case of STACK_WIND - */ -struct stripe_local; /* this itself is used inside the structure; */ - -struct stripe_local { -    struct stripe_local *next; -    call_frame_t *orig_frame; - -    stripe_fd_ctx_t *fctx; - -    /* Used by _cbk functions */ -    struct iatt stbuf; -    struct iatt pre_buf; -    struct iatt post_buf; -    struct iatt preparent; -    struct iatt postparent; - -    off_t stbuf_size; -    off_t prebuf_size; -    off_t postbuf_size; -    off_t preparent_size; -    off_t postparent_size; - -    blkcnt_t stbuf_blocks; -    blkcnt_t prebuf_blocks; -    blkcnt_t postbuf_blocks; -    blkcnt_t preparent_blocks; -    blkcnt_t postparent_blocks; - -    struct stripe_replies *replies; -    struct statvfs statvfs_buf; -    dir_entry_t *entry; - -    int8_t revalidate; -    int8_t failed; -    int8_t unwind; - -    size_t readv_size; -    int32_t entry_count; -    int32_t node_index; -    int32_t call_count; -    int32_t wind_count; /* used instead of child_cound -                           in case of read and write */ -    int32_t op_ret; -    int32_t op_errno; -    int32_t count; -    int32_t flags; -    char *name; -    inode_t *inode; - -    loc_t loc; -    loc_t loc2; - -    mode_t mode; -    dev_t rdev; -    /* For File I/O fops */ -    dict_t *xdata; - -    stripe_xattr_sort_t *xattr_list; -    int32_t xattr_total_len; -    int32_t nallocs; -    char xsel[256]; - -    /* General usage */ -    off_t offset; -    off_t stripe_size; - -    int xattr_self_heal_needed; -    int entry_self_heal_needed; - -    int8_t *list; -    struct gf_flock lock; -    fd_t *fd; -    void *value; -    struct iobref *iobref; -    gf_dirent_t entries; -    gf_dirent_t *dirent; -    dict_t *xattr; -    uuid_t ia_gfid; - -    int xflag; -    mode_t umask; -}; - -typedef struct stripe_local stripe_local_t; -typedef struct stripe_private stripe_private_t; - -/* - * Determine the stripe index of a particular frame based on the translator. - */ -static inline int32_t -stripe_get_frame_index(stripe_fd_ctx_t *fctx, call_frame_t *prev) -{ -    int32_t i, idx = -1; - -    for (i = 0; i < fctx->stripe_count; i++) { -        if (fctx->xl_array[i] == prev->this) { -            idx = i; -            break; -        } -    } - -    return idx; -} - -static inline void -stripe_copy_xl_array(xlator_t **dst, xlator_t **src, int count) -{ -    int i; - -    for (i = 0; i < count; i++) -        dst[i] = src[i]; -} - -void -stripe_local_wipe(stripe_local_t *local); -int32_t -stripe_ctx_handle(xlator_t *this, call_frame_t *prev, stripe_local_t *local, -                  dict_t *dict); -void -stripe_aggregate_xattr(dict_t *dst, dict_t *src); -int32_t -stripe_xattr_request_build(xlator_t *this, dict_t *dict, uint64_t stripe_size, -                           uint32_t stripe_count, uint32_t stripe_index, -                           uint32_t stripe_coalesce); -int32_t -stripe_get_matching_bs(const char *path, stripe_private_t *priv); -int -set_stripe_block_size(xlator_t *this, stripe_private_t *priv, char *data); -int32_t -stripe_iatt_merge(struct iatt *from, struct iatt *to); -int32_t -stripe_fill_pathinfo_xattr(xlator_t *this, stripe_local_t *local, -                           char **xattr_serz); -int32_t -stripe_free_xattr_str(stripe_local_t *local); -int32_t -stripe_xattr_aggregate(char *buffer, stripe_local_t *local, int32_t *total); -off_t -coalesced_offset(off_t offset, uint64_t stripe_size, int stripe_count); -off_t -uncoalesced_size(off_t size, uint64_t stripe_size, int stripe_count, -                 int stripe_index); -int32_t -stripe_fill_lockinfo_xattr(xlator_t *this, stripe_local_t *local, -                           void **xattr_serz); - -/* - * Adjust the size attribute for files if coalesce is enabled. - */ -static inline void -correct_file_size(struct iatt *buf, stripe_fd_ctx_t *fctx, call_frame_t *prev) -{ -    int index; - -    if (!IA_ISREG(buf->ia_type)) -        return; - -    if (!fctx || !fctx->stripe_coalesce) -        return; - -    index = stripe_get_frame_index(fctx, prev); -    buf->ia_size = uncoalesced_size(buf->ia_size, fctx->stripe_size, -                                    fctx->stripe_count, index); -} - -#endif /* _STRIPE_H_ */ diff --git a/xlators/encryption/Makefile.am b/xlators/encryption/Makefile.am deleted file mode 100644 index 36efc6698bd..00000000000 --- a/xlators/encryption/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = rot-13 crypt - -CLEANFILES =  diff --git a/xlators/encryption/crypt/Makefile.am b/xlators/encryption/crypt/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/xlators/encryption/crypt/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/xlators/encryption/crypt/src/Makefile.am b/xlators/encryption/crypt/src/Makefile.am deleted file mode 100644 index 05fd3d5096b..00000000000 --- a/xlators/encryption/crypt/src/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -if ENABLE_CRYPT_XLATOR - -xlator_LTLIBRARIES = crypt.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/encryption - -crypt_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) - -crypt_la_SOURCES = keys.c data.c metadata.c atom.c crypt.c -crypt_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ -	-lssl -lcrypto - -noinst_HEADERS = crypt-common.h crypt-mem-types.h crypt.h metadata.h - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -CLEANFILES = - -else - -noinst_DIST = keys.c data.c metadata.c atom.c crypt.c -noinst_HEADERS = crypt-common.h crypt-mem-types.h crypt.h metadata.h - -endif diff --git a/xlators/encryption/crypt/src/atom.c b/xlators/encryption/crypt/src/atom.c deleted file mode 100644 index bdc37c500a3..00000000000 --- a/xlators/encryption/crypt/src/atom.c +++ /dev/null @@ -1,861 +0,0 @@ -/* -  Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <glusterfs/defaults.h> -#include "crypt-common.h" -#include "crypt.h" - -/* - *                              Glossary - * - * - * cblock            (or cipher block). A logical unit in a file. - *                   cblock size is defined as the number of bits - *                   in an input (or output) block of the block - *                   cipher (*). Cipher block size is a property of - *                   cipher algorithm. E.g. cblock size is 64 bits - *                   for DES, 128 bits for AES, etc. - * - * atomic cipher     A cipher algorithm, which requires some chunks of - * algorithm         text to be padded at left and(or) right sides before - *                   cipher transaform. - * - * - * block (atom)      Minimal chunk of file's data, which doesn't require - *                   padding. We'll consider logical units in a file of - *                   block size (atom size). - * - * cipher algorithm  Atomic cipher algorithm, which requires the last - * with EOF issue    incomplete cblock in a file to be padded with some - *                   data (usually zeros). - * - * - * operation, which  reading/writing from offset, which is not aligned to - * forms a gap at    to atom size - * the beginning - * - * - * operation, which  reading/writing count bytes starting from offset off, - * forms a gap at    so that off+count is not aligned to atom_size - * the end - * - * head block        the first atom affected by an operation, which forms - *                   a gap at the beginning, or(and) at the end. - *                   Сomment. Head block has at least one gap (either at - *                   the beginning, or at the end) - * - * - * tail block        the last atom different from head, affected by an - *                   operation, which forms a gap at the end. - *                   Сomment: Tail block has exactly one gap (at the end). - * - * - * partial block     head or tail block - * - * - * full block        block without gaps. - * - * - * (*) Recommendation for Block Cipher Modes of Operation - *     Methods and Techniques - *     NIST Special Publication 800-38A Edition 2001 - */ - -/* - * atom->offset_at() - */ -static off_t -offset_at_head(struct avec_config *conf) -{ -    return conf->aligned_offset; -} - -static off_t -offset_at_hole_head(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_at_head(get_hole_conf(frame)); -} - -static off_t -offset_at_data_head(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_at_head(get_data_conf(frame)); -} - -static off_t -offset_at_tail(struct avec_config *conf, struct object_cipher_info *object) -{ -    return conf->aligned_offset + -           (conf->off_in_head ? get_atom_size(object) : 0) + -           (conf->nr_full_blocks << get_atom_bits(object)); -} - -static off_t -offset_at_hole_tail(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_at_tail(get_hole_conf(frame), object); -} - -static off_t -offset_at_data_tail(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_at_tail(get_data_conf(frame), object); -} - -static off_t -offset_at_full(struct avec_config *conf, struct object_cipher_info *object) -{ -    return conf->aligned_offset + -           (conf->off_in_head ? get_atom_size(object) : 0); -} - -static off_t -offset_at_data_full(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_at_full(get_data_conf(frame), object); -} - -static off_t -offset_at_hole_full(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_at_full(get_hole_conf(frame), object); -} - -/* - * atom->io_size_nopad() - */ - -static uint32_t -io_size_nopad_head(struct avec_config *conf, struct object_cipher_info *object) -{ -    uint32_t gap_at_beg; -    uint32_t gap_at_end; - -    check_head_block(conf); - -    gap_at_beg = conf->off_in_head; - -    if (has_tail_block(conf) || has_full_blocks(conf) || conf->off_in_tail == 0) -        gap_at_end = 0; -    else -        gap_at_end = get_atom_size(object) - conf->off_in_tail; - -    return get_atom_size(object) - (gap_at_beg + gap_at_end); -} - -static uint32_t -io_size_nopad_tail(struct avec_config *conf, struct object_cipher_info *object) -{ -    check_tail_block(conf); -    return conf->off_in_tail; -} - -static uint32_t -io_size_nopad_full(struct avec_config *conf, struct object_cipher_info *object) -{ -    check_full_block(conf); -    return get_atom_size(object); -} - -static uint32_t -io_size_nopad_data_head(call_frame_t *frame, struct object_cipher_info *object) -{ -    return io_size_nopad_head(get_data_conf(frame), object); -} - -static uint32_t -io_size_nopad_hole_head(call_frame_t *frame, struct object_cipher_info *object) -{ -    return io_size_nopad_head(get_hole_conf(frame), object); -} - -static uint32_t -io_size_nopad_data_tail(call_frame_t *frame, struct object_cipher_info *object) -{ -    return io_size_nopad_tail(get_data_conf(frame), object); -} - -static uint32_t -io_size_nopad_hole_tail(call_frame_t *frame, struct object_cipher_info *object) -{ -    return io_size_nopad_tail(get_hole_conf(frame), object); -} - -static uint32_t -io_size_nopad_data_full(call_frame_t *frame, struct object_cipher_info *object) -{ -    return io_size_nopad_full(get_data_conf(frame), object); -} - -static uint32_t -io_size_nopad_hole_full(call_frame_t *frame, struct object_cipher_info *object) -{ -    return io_size_nopad_full(get_hole_conf(frame), object); -} - -static uint32_t -offset_in_head(struct avec_config *conf) -{ -    check_cursor_head(conf); - -    return conf->off_in_head; -} - -static uint32_t -offset_in_tail(call_frame_t *frame, struct object_cipher_info *object) -{ -    return 0; -} - -static uint32_t -offset_in_full(struct avec_config *conf, struct object_cipher_info *object) -{ -    check_cursor_full(conf); - -    if (has_head_block(conf)) -        return (conf->cursor - 1) << get_atom_bits(object); -    else -        return conf->cursor << get_atom_bits(object); -} - -static uint32_t -offset_in_data_head(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_in_head(get_data_conf(frame)); -} - -static uint32_t -offset_in_hole_head(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_in_head(get_hole_conf(frame)); -} - -static uint32_t -offset_in_data_full(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_in_full(get_data_conf(frame), object); -} - -static uint32_t -offset_in_hole_full(call_frame_t *frame, struct object_cipher_info *object) -{ -    return offset_in_full(get_hole_conf(frame), object); -} - -/* - * atom->rmw() - */ -/* - * Pre-conditions: - * @vec contains plain text of the latest - * version. - * - * Uptodate gaps of the @partial block with - * this plain text, encrypt the whole block - * and write the result to disk. - */ -static int32_t -rmw_partial_block(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, struct iovec *vec, -                  int32_t count, struct iatt *stbuf, struct iobref *iobref, -                  struct rmw_atom *atom) -{ -    size_t was_read = 0; -    uint64_t file_size; -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = &local->info->cinfo; - -    struct iovec *partial = atom->get_iovec(frame, 0); -    struct avec_config *conf = atom->get_config(frame); -    end_writeback_handler_t end_writeback_partial_block; -#if DEBUG_CRYPT -    gf_boolean_t check_last_cblock = _gf_false; -#endif -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0) -        goto exit; - -    file_size = local->cur_file_size; -    was_read = op_ret; - -    if (atom->locality == HEAD_ATOM && conf->off_in_head) { -        /* -         * head atom with a non-uptodate gap -         * at the beginning -         * -         * fill the gap with plain text of the -         * latest version. Convert a part of hole -         * (if any) to zeros. -         */ -        int32_t i; -        int32_t copied = 0; -        int32_t to_gap; /* amount of data needed to uptodate -                           the gap at the beginning */ -#if 0 -		int32_t hole = 0; /* The part of the hole which -				   * got in the head block */ -#endif /* 0 */ -        to_gap = conf->off_in_head; - -        if (was_read < to_gap) { -            if (file_size > offset_at_head(conf) + was_read) { -                /* -                 * It is impossible to uptodate -                 * head block: too few bytes have -                 * been read from disk, so that -                 * partial write is impossible. -                 * -                 * It could happen because of many -                 * reasons: IO errors, (meta)data -                 * corruption in the local file system, -                 * etc. -                 */ -                gf_log(this->name, GF_LOG_WARNING, -                       "Can not uptodate a gap at the beginning"); -                local->op_ret = -1; -                local->op_errno = EIO; -                goto exit; -            } -#if 0 -			hole = to_gap - was_read; -#endif /* 0 */ -            to_gap = was_read; -        } -        /* -         * uptodate the gap at the beginning -         */ -        for (i = 0; i < count && copied < to_gap; i++) { -            int32_t to_copy; - -            to_copy = vec[i].iov_len; -            if (to_copy > to_gap - copied) -                to_copy = to_gap - copied; - -            memcpy(partial->iov_base, vec[i].iov_base, to_copy); -            copied += to_copy; -        } -#if 0 -		/* -		 * If possible, convert part of the -		 * hole, which got in the head block -		 */ -		ret = TRY_LOCK(&local->hole_lock); -		if (!ret) { -			if (local->hole_handled) -				/* -				 * already converted by -				 * crypt_writev_cbk() -				 */ -				UNLOCK(&local->hole_lock); -			else { -				/* -				 * convert the part of the hole -				 * which got in the head block -				 * to zeros. -				 * -				 * Update the orig_offset to make -				 * sure writev_cbk() won't care -				 * about this part of the hole. -				 * -				 */ -				memset(partial->iov_base + to_gap, 0, hole); - -				conf->orig_offset -= hole; -				conf->orig_size += hole; -				UNLOCK(&local->hole_lock); -			} -		} -		else /* -		      * conversion is being performed -		      * by crypt_writev_cbk() -		      */ -			; -#endif /* 0 */ -    } -    if (atom->locality == TAIL_ATOM || -        (!has_tail_block(conf) && conf->off_in_tail)) { -        /* -         * tail atom, or head atom with a non-uptodate -         * gap at the end. -         * -         * fill the gap at the end of the block -         * with plain text of the latest version. -         * Pad the result, (if needed) -         */ -        int32_t i; -        int32_t to_gap; -        int copied; -        off_t off_in_tail; -        int32_t to_copy; - -        off_in_tail = conf->off_in_tail; -        to_gap = conf->gap_in_tail; - -        if (to_gap && was_read < off_in_tail + to_gap) { -            /* -             * It is impossible to uptodate -             * the gap at the end: too few bytes -             * have been read from disk, so that -             * partial write is impossible. -             * -             * It could happen because of many -             * reasons: IO errors, (meta)data -             * corruption in the local file system, -             * etc. -             */ -            gf_log(this->name, GF_LOG_WARNING, -                   "Can not uptodate a gap at the end"); -            local->op_ret = -1; -            local->op_errno = EIO; -            goto exit; -        } -        /* -         * uptodate the gap at the end -         */ -        copied = 0; -        to_copy = to_gap; -        for (i = count - 1; i >= 0 && to_copy > 0; i--) { -            uint32_t from_vec, off_in_vec; - -            off_in_vec = 0; -            from_vec = vec[i].iov_len; -            if (from_vec > to_copy) { -                off_in_vec = from_vec - to_copy; -                from_vec = to_copy; -            } -            memcpy(partial->iov_base + off_in_tail + to_gap - copied - from_vec, -                   vec[i].iov_base + off_in_vec, from_vec); - -            gf_log( -                this->name, GF_LOG_DEBUG, -                "uptodate %d bytes at tail. Offset at target(source): %d(%d)", -                (int)from_vec, (int)off_in_tail + to_gap - copied - from_vec, -                (int)off_in_vec); - -            copied += from_vec; -            to_copy -= from_vec; -        } -        partial->iov_len = off_in_tail + to_gap; - -        if (object_alg_should_pad(object)) { -            int32_t resid = 0; -            resid = partial->iov_len & (object_alg_blksize(object) - 1); -            if (resid) { -                /* -                 * append a new EOF padding -                 */ -                local->eof_padding_size = object_alg_blksize(object) - resid; - -                gf_log(this->name, GF_LOG_DEBUG, "set padding size %d", -                       local->eof_padding_size); - -                memset(partial->iov_base + partial->iov_len, 1, -                       local->eof_padding_size); -                partial->iov_len += local->eof_padding_size; -#if DEBUG_CRYPT -                gf_log(this->name, GF_LOG_DEBUG, -                       "pad cblock with %d zeros:", local->eof_padding_size); -                dump_cblock(this, (unsigned char *)partial->iov_base + -                                      partial->iov_len - -                                      object_alg_blksize(object)); -                check_last_cblock = _gf_true; -#endif -            } -        } -    } -    /* -     * encrypt the whole block -     */ -    encrypt_aligned_iov(object, partial, 1, atom->offset_at(frame, object)); -#if DEBUG_CRYPT -    if (check_last_cblock == _gf_true) { -        gf_log(this->name, GF_LOG_DEBUG, "encrypt last cblock with offset %llu", -               (unsigned long long)atom->offset_at(frame, object)); -        dump_cblock(this, (unsigned char *)partial->iov_base + -                              partial->iov_len - object_alg_blksize(object)); -    } -#endif -    set_local_io_params_writev(frame, object, atom, -                               atom->offset_at(frame, object), -                               iov_length(partial, 1)); -    /* -     * write the whole block to disk -     */ -    end_writeback_partial_block = dispatch_end_writeback(local->fop); -    conf->cursor++; -    STACK_WIND(frame, end_writeback_partial_block, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->writev, local->fd, partial, 1, -               atom->offset_at(frame, object), local->flags, local->iobref_data, -               local->xdata); - -    gf_log("crypt", GF_LOG_DEBUG, -           "submit partial block: %d bytes from %d offset", -           (int)iov_length(partial, 1), (int)atom->offset_at(frame, object)); -exit: -    return 0; -} - -/* - * Perform a (read-)modify-write sequence. - * This should be performed only after approval - * of upper server-side manager, i.e. the caller - * needs to make sure this is his turn to rmw. - */ -void -submit_partial(call_frame_t *frame, xlator_t *this, fd_t *fd, -               atom_locality_type ltype) -{ -    int32_t ret; -    dict_t *dict; -    struct rmw_atom *atom; -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = &local->info->cinfo; - -    atom = atom_by_types(local->active_setup, ltype); -    /* -     * To perform the "read" component of the read-modify-write -     * sequence the crypt translator does stack_wind to itself. -     * -     * Pass current file size to crypt_readv() -     */ -    dict = dict_new(); -    if (!dict) { -        /* -         * FIXME: Handle the error -         */ -        gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict"); -        return; -    } -    ret = dict_set(dict, FSIZE_XATTR_PREFIX, -                   data_from_uint64(local->cur_file_size)); -    if (ret) { -        /* -         * FIXME: Handle the error -         */ -        dict_unref(dict); -        gf_log("crypt", GF_LOG_WARNING, "Can not set dict"); -        goto exit; -    } -    STACK_WIND(frame, atom->rmw, this, this->fops->readv,  /* crypt_readv */ -               fd, atom->count_to_uptodate(frame, object), /* count */ -               atom->offset_at(frame, object), /* offset to read from */ -               0, dict); -exit: -    dict_unref(dict); -} - -/* - * submit blocks of FULL_ATOM type - */ -void -submit_full(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = &local->info->cinfo; -    struct rmw_atom *atom = atom_by_types(local->active_setup, FULL_ATOM); -    uint32_t count;       /* total number of full blocks to submit */ -    uint32_t granularity; /* number of blocks to submit in one iteration */ - -    uint64_t off_in_file;        /* start offset in the file, bytes */ -    uint32_t off_in_atom;        /* start offset in the atom, blocks */ -    uint32_t blocks_written = 0; /* blocks written for this submit */ - -    struct avec_config *conf = atom->get_config(frame); -    end_writeback_handler_t end_writeback_full_block; -    /* -     * Write full blocks by groups of granularity size. -     */ -    end_writeback_full_block = dispatch_end_writeback(local->fop); - -    if (is_ordered_mode(frame)) { -        uint32_t skip = has_head_block(conf) ? 1 : 0; -        count = 1; -        granularity = 1; -        /* -         * calculate start offset using cursor value; -         * here we should take into account head block, -         * which corresponds to cursor value 0. -         */ -        off_in_file = atom->offset_at(frame, object) + -                      ((conf->cursor - skip) << get_atom_bits(object)); -        off_in_atom = conf->cursor - skip; -    } else { -        /* -         * in parallel mode -         */ -        count = conf->nr_full_blocks; -        granularity = MAX_IOVEC; -        off_in_file = atom->offset_at(frame, object); -        off_in_atom = 0; -    } -    while (count) { -        uint32_t blocks_to_write = count; - -        if (blocks_to_write > granularity) -            blocks_to_write = granularity; -        if (conf->type == HOLE_ATOM) -            /* -             * reset iovec before encryption -             */ -            memset(atom->get_iovec(frame, 0)->iov_base, 0, -                   get_atom_size(object)); -        /* -         * encrypt the group -         */ -        encrypt_aligned_iov( -            object, atom->get_iovec(frame, off_in_atom + blocks_written), -            blocks_to_write, -            off_in_file + (blocks_written << get_atom_bits(object))); - -        set_local_io_params_writev( -            frame, object, atom, -            off_in_file + (blocks_written << get_atom_bits(object)), -            blocks_to_write << get_atom_bits(object)); - -        conf->cursor += blocks_to_write; - -        STACK_WIND(frame, end_writeback_full_block, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->writev, local->fd, -                   atom->get_iovec(frame, off_in_atom + blocks_written), -                   blocks_to_write, -                   off_in_file + (blocks_written << get_atom_bits(object)), -                   local->flags, -                   local->iobref_data ? local->iobref_data : local->iobref, -                   local->xdata); - -        gf_log("crypt", GF_LOG_DEBUG, "submit %d full blocks from %d offset", -               blocks_to_write, -               (int)(off_in_file + (blocks_written << get_atom_bits(object)))); - -        count -= blocks_to_write; -        blocks_written += blocks_to_write; -    } -    return; -} - -static int32_t -rmw_data_head(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iovec *vec, int32_t count, -              struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) -{ -    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, -                             stbuf, iobref, -                             atom_by_types(DATA_ATOM, HEAD_ATOM)); -} - -static int32_t -rmw_data_tail(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iovec *vec, int32_t count, -              struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) -{ -    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, -                             stbuf, iobref, -                             atom_by_types(DATA_ATOM, TAIL_ATOM)); -} - -static int32_t -rmw_hole_head(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iovec *vec, int32_t count, -              struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) -{ -    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, -                             stbuf, iobref, -                             atom_by_types(HOLE_ATOM, HEAD_ATOM)); -} - -static int32_t -rmw_hole_tail(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iovec *vec, int32_t count, -              struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) -{ -    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, -                             stbuf, iobref, -                             atom_by_types(HOLE_ATOM, TAIL_ATOM)); -} - -/* - * atom->count_to_uptodate() - */ -static uint32_t -count_to_uptodate_head(struct avec_config *conf, -                       struct object_cipher_info *object) -{ -    if (conf->acount == 1 && conf->off_in_tail) -        return get_atom_size(object); -    else -        /* there is no need to read the whole head block */ -        return conf->off_in_head; -} - -static uint32_t -count_to_uptodate_tail(struct avec_config *conf, -                       struct object_cipher_info *object) -{ -    /* we need to read the whole tail block */ -    return get_atom_size(object); -} - -static uint32_t -count_to_uptodate_data_head(call_frame_t *frame, -                            struct object_cipher_info *object) -{ -    return count_to_uptodate_head(get_data_conf(frame), object); -} - -static uint32_t -count_to_uptodate_data_tail(call_frame_t *frame, -                            struct object_cipher_info *object) -{ -    return count_to_uptodate_tail(get_data_conf(frame), object); -} - -static uint32_t -count_to_uptodate_hole_head(call_frame_t *frame, -                            struct object_cipher_info *object) -{ -    return count_to_uptodate_head(get_hole_conf(frame), object); -} - -static uint32_t -count_to_uptodate_hole_tail(call_frame_t *frame, -                            struct object_cipher_info *object) -{ -    return count_to_uptodate_tail(get_hole_conf(frame), object); -} - -/* atom->get_config() */ - -static struct avec_config * -get_config_data(call_frame_t *frame) -{ -    return &((crypt_local_t *)frame->local)->data_conf; -} - -static struct avec_config * -get_config_hole(call_frame_t *frame) -{ -    return &((crypt_local_t *)frame->local)->hole_conf; -} - -/* - * atom->get_iovec() - */ -static struct iovec * -get_iovec_hole_head(call_frame_t *frame, uint32_t count) -{ -    struct avec_config *conf = get_hole_conf(frame); - -    return conf->avec; -} - -static struct iovec * -get_iovec_hole_full(call_frame_t *frame, uint32_t count) -{ -    struct avec_config *conf = get_hole_conf(frame); - -    return conf->avec + (conf->off_in_head ? 1 : 0); -} - -static struct iovec * -get_iovec_hole_tail(call_frame_t *frame, uint32_t count) -{ -    struct avec_config *conf = get_hole_conf(frame); - -    return conf->avec + (conf->blocks_in_pool - 1); -} - -static struct iovec * -get_iovec_data_head(call_frame_t *frame, uint32_t count) -{ -    struct avec_config *conf = get_data_conf(frame); - -    return conf->avec; -} - -static struct iovec * -get_iovec_data_full(call_frame_t *frame, uint32_t count) -{ -    struct avec_config *conf = get_data_conf(frame); - -    return conf->avec + (conf->off_in_head ? 1 : 0) + count; -} - -static struct iovec * -get_iovec_data_tail(call_frame_t *frame, uint32_t count) -{ -    struct avec_config *conf = get_data_conf(frame); - -    return conf->avec + (conf->off_in_head ? 1 : 0) + conf->nr_full_blocks; -} - -static struct rmw_atom atoms[LAST_DATA_TYPE][LAST_LOCALITY_TYPE] = { -    [DATA_ATOM][HEAD_ATOM] = {.locality = HEAD_ATOM, -                              .rmw = rmw_data_head, -                              .offset_at = offset_at_data_head, -                              .offset_in = offset_in_data_head, -                              .get_iovec = get_iovec_data_head, -                              .io_size_nopad = io_size_nopad_data_head, -                              .count_to_uptodate = count_to_uptodate_data_head, -                              .get_config = get_config_data}, -    [DATA_ATOM][TAIL_ATOM] = {.locality = TAIL_ATOM, -                              .rmw = rmw_data_tail, -                              .offset_at = offset_at_data_tail, -                              .offset_in = offset_in_tail, -                              .get_iovec = get_iovec_data_tail, -                              .io_size_nopad = io_size_nopad_data_tail, -                              .count_to_uptodate = count_to_uptodate_data_tail, -                              .get_config = get_config_data}, -    [DATA_ATOM][FULL_ATOM] = {.locality = FULL_ATOM, -                              .offset_at = offset_at_data_full, -                              .offset_in = offset_in_data_full, -                              .get_iovec = get_iovec_data_full, -                              .io_size_nopad = io_size_nopad_data_full, -                              .get_config = get_config_data}, -    [HOLE_ATOM][HEAD_ATOM] = {.locality = HEAD_ATOM, -                              .rmw = rmw_hole_head, -                              .offset_at = offset_at_hole_head, -                              .offset_in = offset_in_hole_head, -                              .get_iovec = get_iovec_hole_head, -                              .io_size_nopad = io_size_nopad_hole_head, -                              .count_to_uptodate = count_to_uptodate_hole_head, -                              .get_config = get_config_hole}, -    [HOLE_ATOM][TAIL_ATOM] = {.locality = TAIL_ATOM, -                              .rmw = rmw_hole_tail, -                              .offset_at = offset_at_hole_tail, -                              .offset_in = offset_in_tail, -                              .get_iovec = get_iovec_hole_tail, -                              .io_size_nopad = io_size_nopad_hole_tail, -                              .count_to_uptodate = count_to_uptodate_hole_tail, -                              .get_config = get_config_hole}, -    [HOLE_ATOM][FULL_ATOM] = {.locality = FULL_ATOM, -                              .offset_at = offset_at_hole_full, -                              .offset_in = offset_in_hole_full, -                              .get_iovec = get_iovec_hole_full, -                              .io_size_nopad = io_size_nopad_hole_full, -                              .get_config = get_config_hole}}; - -struct rmw_atom * -atom_by_types(atom_data_type data, atom_locality_type locality) -{ -    return &atoms[data][locality]; -} - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/crypt-common.h b/xlators/encryption/crypt/src/crypt-common.h deleted file mode 100644 index 123d5c2a631..00000000000 --- a/xlators/encryption/crypt/src/crypt-common.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -  Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __CRYPT_COMMON_H__ -#define __CRYPT_COMMON_H__ - -#define INVAL_SUBVERSION_NUMBER (0xff) -#define CRYPT_INVAL_OP (GF_FOP_NULL) - -#define CRYPTO_FORMAT_PREFIX "trusted.glusterfs.crypt.att.cfmt" -#define FSIZE_XATTR_PREFIX "trusted.glusterfs.crypt.att.size" -#define SUBREQ_PREFIX "trusted.glusterfs.crypt.msg.sreq" -#define FSIZE_MSG_PREFIX "trusted.glusterfs.crypt.msg.size" -#define DE_MSG_PREFIX "trusted.glusterfs.crypt.msg.dent" -#define REQUEST_ID_PREFIX "trusted.glusterfs.crypt.msg.rqid" -#define MSGFLAGS_PREFIX "trusted.glusterfs.crypt.msg.xfgs" - -/* messages for crypt_open() */ -#define MSGFLAGS_REQUEST_MTD_RLOCK 1 /* take read lock and don't unlock */ -#define MSGFLAGS_REQUEST_MTD_WLOCK 2 /* take write lock and don't unlock */ - -#define AES_BLOCK_BITS (4) /* AES_BLOCK_SIZE == 1 << AES_BLOCK_BITS */ - -#define noop                                                                   \ -    do {                                                                       \ -        ;                                                                      \ -    } while (0) -#define cassert(cond)                                                          \ -    ({                                                                         \ -        switch (-1) {                                                          \ -            case (cond):                                                       \ -            case 0:                                                            \ -                break;                                                         \ -        }                                                                      \ -    }) -#define __round_mask(x, y) ((__typeof__(x))((y)-1)) -#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) - -/* - * Format of file's metadata - */ -struct crypt_format { -    uint8_t loader_id;    /* version of metadata loader */ -    uint8_t versioned[0]; /* file's metadata of specific version */ -} __attribute__((packed)); - -typedef enum { AES_CIPHER_ALG, LAST_CIPHER_ALG } cipher_alg_t; - -typedef enum { XTS_CIPHER_MODE, LAST_CIPHER_MODE } cipher_mode_t; - -typedef enum { MTD_LOADER_V1, LAST_MTD_LOADER } mtd_loader_id; - -static inline void -msgflags_set_mtd_rlock(uint32_t *flags) -{ -    *flags |= MSGFLAGS_REQUEST_MTD_RLOCK; -} - -static inline void -msgflags_set_mtd_wlock(uint32_t *flags) -{ -    *flags |= MSGFLAGS_REQUEST_MTD_WLOCK; -} - -static inline gf_boolean_t -msgflags_check_mtd_rlock(uint32_t *flags) -{ -    return *flags & MSGFLAGS_REQUEST_MTD_RLOCK; -} - -static inline gf_boolean_t -msgflags_check_mtd_wlock(uint32_t *flags) -{ -    return *flags & MSGFLAGS_REQUEST_MTD_WLOCK; -} - -static inline gf_boolean_t -msgflags_check_mtd_lock(uint32_t *flags) -{ -    return msgflags_check_mtd_rlock(flags) || msgflags_check_mtd_wlock(flags); -} - -/* - * returns number of logical blocks occupied - * (maybe partially) by @count bytes - * at offset @start. - */ -static inline off_t -logical_blocks_occupied(uint64_t start, off_t count, int blkbits) -{ -    return ((start + count - 1) >> blkbits) - (start >> blkbits) + 1; -} - -/* - * are two bytes (represented by offsets @off1 - * and @off2 respectively) in the same logical - * block. - */ -static inline int -in_same_lblock(uint64_t off1, uint64_t off2, int blkbits) -{ -    return off1 >> blkbits == off2 >> blkbits; -} - -static inline void -dump_cblock(xlator_t *this, unsigned char *buf) -{ -    gf_log(this->name, GF_LOG_DEBUG, -           "dump cblock: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", -           (buf)[0], (buf)[1], (buf)[2], (buf)[3], (buf)[4], (buf)[5], (buf)[6], -           (buf)[7], (buf)[8], (buf)[9], (buf)[10], (buf)[11], (buf)[12], -           (buf)[13], (buf)[14], (buf)[15]); -} - -#endif /* __CRYPT_COMMON_H__ */ - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/crypt-mem-types.h b/xlators/encryption/crypt/src/crypt-mem-types.h deleted file mode 100644 index e756ea4a23c..00000000000 --- a/xlators/encryption/crypt/src/crypt-mem-types.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -  Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __CRYPT_MEM_TYPES_H__ -#define __CRYPT_MEM_TYPES_H__ - -#include <glusterfs/mem-types.h> - -enum gf_crypt_mem_types_ { -    gf_crypt_mt_priv = gf_common_mt_end + 1, -    gf_crypt_mt_inode, -    gf_crypt_mt_data, -    gf_crypt_mt_mtd, -    gf_crypt_mt_loc, -    gf_crypt_mt_iatt, -    gf_crypt_mt_key, -    gf_crypt_mt_iovec, -    gf_crypt_mt_char, -    gf_crypt_mt_local, -    gf_crypt_mt_end, -}; - -#endif /* __CRYPT_MEM_TYPES_H__ */ - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/crypt.c b/xlators/encryption/crypt/src/crypt.c deleted file mode 100644 index 02253642cc9..00000000000 --- a/xlators/encryption/crypt/src/crypt.c +++ /dev/null @@ -1,3906 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ -#include <ctype.h> -#include <sys/uio.h> - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/defaults.h> - -#include "crypt-common.h" -#include "crypt.h" - -static void -init_inode_info_head(struct crypt_inode_info *info, fd_t *fd); -static int32_t -init_inode_info_tail(struct crypt_inode_info *info, -                     struct master_cipher_info *master); -static int32_t -prepare_for_submit_hole(call_frame_t *frame, xlator_t *this, uint64_t from, -                        off_t size); -static int32_t -load_file_size(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata); -static void -do_ordered_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype); -static void -do_parallel_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype); -static void -put_one_call_open(call_frame_t *frame); -static void -put_one_call_readv(call_frame_t *frame, xlator_t *this); -static void -put_one_call_writev(call_frame_t *frame, xlator_t *this); -static void -put_one_call_ftruncate(call_frame_t *frame, xlator_t *this); -static void -free_avec(struct iovec *avec, char **pool, int blocks_in_pool); -static void -free_avec_data(crypt_local_t *local); -static void -free_avec_hole(crypt_local_t *local); - -static crypt_local_t * -crypt_alloc_local(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop) -{ -    crypt_local_t *local = NULL; - -    local = GF_CALLOC(1, sizeof(crypt_local_t), gf_crypt_mt_local); -    if (!local) { -        gf_log(this->name, GF_LOG_ERROR, "out of memory"); -        return NULL; -    } -    local->fop = fop; -    LOCK_INIT(&local->hole_lock); -    LOCK_INIT(&local->call_lock); -    LOCK_INIT(&local->rw_count_lock); - -    frame->local = local; -    return local; -} - -struct crypt_inode_info * -get_crypt_inode_info(inode_t *inode, xlator_t *this) -{ -    int ret; -    uint64_t value = 0; -    struct crypt_inode_info *info; - -    ret = inode_ctx_get(inode, this, &value); -    if (ret == -1) { -        gf_log(this->name, GF_LOG_WARNING, "Can not get inode info"); -        return NULL; -    } -    info = (struct crypt_inode_info *)(long)value; -    if (info == NULL) { -        gf_log(this->name, GF_LOG_WARNING, "Can not obtain inode info"); -        return NULL; -    } -    return info; -} - -static struct crypt_inode_info * -local_get_inode_info(crypt_local_t *local, xlator_t *this) -{ -    if (local->info) -        return local->info; -    local->info = get_crypt_inode_info(local->fd->inode, this); -    return local->info; -} - -static struct crypt_inode_info * -alloc_inode_info(crypt_local_t *local, loc_t *loc) -{ -    struct crypt_inode_info *info; - -    info = GF_CALLOC(1, sizeof(struct crypt_inode_info), gf_crypt_mt_inode); -    if (!info) { -        local->op_ret = -1; -        local->op_errno = ENOMEM; -        gf_log("crypt", GF_LOG_WARNING, "Can not allocate inode info"); -        return NULL; -    } -#if DEBUG_CRYPT -    info->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -    if (!info->loc) { -        gf_log("crypt", GF_LOG_WARNING, "Can not allocate loc"); -        GF_FREE(info); -        return NULL; -    } -    if (loc_copy(info->loc, loc)) { -        GF_FREE(info->loc); -        GF_FREE(info); -        return NULL; -    } -#endif /* DEBUG_CRYPT */ - -    local->info = info; -    return info; -} - -static void -free_inode_info(struct crypt_inode_info *info) -{ -#if DEBUG_CRYPT -    loc_wipe(info->loc); -    GF_FREE(info->loc); -#endif -    memset(info, 0, sizeof(*info)); -    GF_FREE(info); -} - -int -crypt_forget(xlator_t *this, inode_t *inode) -{ -    uint64_t ctx_addr = 0; -    if (!inode_ctx_del(inode, this, &ctx_addr)) -        free_inode_info((struct crypt_inode_info *)(long)ctx_addr); -    return 0; -} - -#if DEBUG_CRYPT -static void -check_read(call_frame_t *frame, xlator_t *this, int32_t read, struct iovec *vec, -           int32_t count, struct iatt *stbuf) -{ -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = get_object_cinfo(local->info); -    struct avec_config *conf = &local->data_conf; -    uint32_t resid = stbuf->ia_size & (object_alg_blksize(object) - 1); - -    if (read <= 0) -        return; -    if (read != iov_length(vec, count)) -        gf_log("crypt", GF_LOG_DEBUG, -               "op_ret differs from amount of read bytes"); - -    if (object_alg_should_pad(object) && -        (read & (object_alg_blksize(object) - 1))) -        gf_log("crypt", GF_LOG_DEBUG, -               "bad amount of read bytes (!= 0 mod(cblock size))"); - -    if (conf->aligned_offset + read > -        stbuf->ia_size + (resid ? object_alg_blksize(object) - resid : 0)) -        gf_log("crypt", GF_LOG_DEBUG, "bad amount of read bytes (too large))"); -} - -#define PT_BYTES_TO_DUMP (32) -static void -dump_plain_text(crypt_local_t *local, struct iovec *avec) -{ -    int32_t to_dump; -    char str[PT_BYTES_TO_DUMP + 1]; - -    if (!avec) -        return; -    to_dump = avec->iov_len; -    if (to_dump > PT_BYTES_TO_DUMP) -        to_dump = PT_BYTES_TO_DUMP; -    memcpy(str, avec->iov_base, to_dump); -    memset(str + to_dump, '0', 1); -    gf_log("crypt", GF_LOG_DEBUG, "Read file: %s", str); -} - -static int32_t -data_conf_invariant(struct avec_config *conf) -{ -    return conf->acount == !!has_head_block(conf) + !!has_tail_block(conf) + -                               conf->nr_full_blocks; -} - -static int32_t -hole_conf_invariant(struct avec_config *conf) -{ -    return conf->blocks_in_pool == !!has_head_block(conf) + -                                       !!has_tail_block(conf) + -                                       !!has_full_blocks(conf); -} - -static void -crypt_check_conf(struct avec_config *conf) -{ -    int32_t ret = 0; -    const char *msg; - -    switch (conf->type) { -        case DATA_ATOM: -            msg = "data"; -            ret = data_conf_invariant(conf); -            break; -        case HOLE_ATOM: -            msg = "hole"; -            ret = hole_conf_invariant(conf); -            break; -        default: -            msg = "unknown"; -    } -    if (!ret) -        gf_log("crypt", GF_LOG_DEBUG, "bad %s conf", msg); -} - -static void -check_buf(call_frame_t *frame, xlator_t *this, struct iatt *buf) -{ -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = &local->info->cinfo; -    uint64_t local_file_size; - -    switch (local->fop) { -        case GF_FOP_FTRUNCATE: -            return; -        case GF_FOP_WRITE: -            local_file_size = local->new_file_size; -            break; -        case GF_FOP_READ: -            if (parent_is_crypt_xlator(frame, this)) -                return; -            local_file_size = local->cur_file_size; -            break; -        default: -            gf_log("crypt", GF_LOG_DEBUG, "bad file operation"); -            return; -    } -    if (buf->ia_size != round_up(local_file_size, object_alg_blksize(object))) -        gf_log("crypt", GF_LOG_DEBUG, -               "bad ia_size in buf (%llu), should be %llu", -               (unsigned long long)buf->ia_size, -               (unsigned long long)round_up(local_file_size, -                                            object_alg_blksize(object))); -} - -#else -#define check_read(frame, this, op_ret, vec, count, stbuf) noop -#define dump_plain_text(local, avec) noop -#define crypt_check_conf(conf) noop -#define check_buf(frame, this, buf) noop -#endif /* DEBUG_CRYPT */ - -/* - * Pre-conditions: - * @vec represents a ciphertext of expanded size and - * aligned offset. - * - * Compound a temporal vector @avec with block-aligned - * components, decrypt and fix it up to represent a chunk - * of data corresponding to the original size and offset. - * Pass the result to the next translator. - */ -int32_t -crypt_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, struct iovec *vec, -                int32_t count, struct iatt *stbuf, struct iobref *iobref, -                dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    struct avec_config *conf = &local->data_conf; -    struct object_cipher_info *object = &local->info->cinfo; - -    struct iovec *avec; -    uint32_t i; -    uint32_t to_vec; -    uint32_t to_user; - -    check_buf(frame, this, stbuf); -    check_read(frame, this, op_ret, vec, count, stbuf); - -    local->op_ret = op_ret; -    local->op_errno = op_errno; -    local->iobref = iobref_ref(iobref); - -    local->buf = *stbuf; -    local->buf.ia_size = local->cur_file_size; - -    if (op_ret <= 0 || count == 0 || vec[0].iov_len == 0) -        goto put_one_call; - -    if (conf->orig_offset >= local->cur_file_size) { -        local->op_ret = 0; -        goto put_one_call; -    } -    /* -     * correct config params with real file size -     * and actual amount of bytes read -     */ -    set_config_offsets(frame, this, conf->orig_offset, op_ret, DATA_ATOM, 0); - -    if (conf->orig_offset + conf->orig_size > local->cur_file_size) -        conf->orig_size = local->cur_file_size - conf->orig_offset; -    /* -     * calculate amount of data to be returned -     * to user. -     */ -    to_user = op_ret; -    if (conf->aligned_offset + to_user <= conf->orig_offset) { -        gf_log(this->name, GF_LOG_WARNING, "Incomplete read"); -        local->op_ret = -1; -        local->op_errno = EIO; -        goto put_one_call; -    } -    to_user -= (conf->aligned_offset - conf->orig_offset); - -    if (to_user > conf->orig_size) -        to_user = conf->orig_size; -    local->rw_count = to_user; - -    op_errno = set_config_avec_data(this, local, conf, object, vec, count); -    if (op_errno) { -        local->op_ret = -1; -        local->op_errno = op_errno; -        goto put_one_call; -    } -    avec = conf->avec; -#if DEBUG_CRYPT -    if (conf->off_in_tail != 0 && -        conf->off_in_tail < object_alg_blksize(object) && -        object_alg_should_pad(object)) -        gf_log(this->name, GF_LOG_DEBUG, "Bad offset in tail %d", -               conf->off_in_tail); -    if (iov_length(vec, count) != 0 && -        in_same_lblock(conf->orig_offset + iov_length(vec, count) - 1, -                       local->cur_file_size - 1, object_alg_blkbits(object))) { -        gf_log(this->name, GF_LOG_DEBUG, "Compound last cblock"); -        dump_cblock(this, (unsigned char *)(avec[conf->acount - 1].iov_base) + -                              avec[conf->acount - 1].iov_len - -                              object_alg_blksize(object)); -        dump_cblock(this, (unsigned char *)(vec[count - 1].iov_base) + -                              vec[count - 1].iov_len - -                              object_alg_blksize(object)); -    } -#endif -    decrypt_aligned_iov(object, avec, conf->acount, conf->aligned_offset); -    /* -     * pass proper plain data to user -     */ -    avec[0].iov_base += (conf->aligned_offset - conf->orig_offset); -    avec[0].iov_len -= (conf->aligned_offset - conf->orig_offset); - -    to_vec = to_user; -    for (i = 0; i < conf->acount; i++) { -        if (avec[i].iov_len > to_vec) -            avec[i].iov_len = to_vec; -        to_vec -= avec[i].iov_len; -    } -put_one_call: -    put_one_call_readv(frame, this); -    return 0; -} - -static int32_t -do_readv(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -         int32_t op_errno, dict_t *dict, dict_t *xdata) -{ -    data_t *data; -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        goto error; -    /* -     * extract regular file size -     */ -    data = dict_get(dict, FSIZE_XATTR_PREFIX); -    if (!data) { -        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -        op_errno = EIO; -        goto error; -    } -    local->cur_file_size = data_to_uint64(data); - -    get_one_call(frame); -    STACK_WIND(frame, crypt_readv_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readv, local->fd, -               /* -                * FIXME: read amount can be reduced -                */ -               local->data_conf.expanded_size, local->data_conf.aligned_offset, -               local->flags, local->xdata); -    return 0; -error: -    local->op_ret = -1; -    local->op_errno = op_errno; - -    get_one_call(frame); -    put_one_call_readv(frame, this); -    return 0; -} - -static int32_t -crypt_readv_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        goto error; -    /* -     * An access has been granted, -     * retrieve file size -     */ -    STACK_WIND(frame, do_readv, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fgetxattr, local->fd, -               FSIZE_XATTR_PREFIX, NULL); -    return 0; -error: -    fd_unref(local->fd); -    if (local->xdata) -        dict_unref(local->xdata); -    CRYPT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); -    return 0; -} - -static int32_t -readv_trivial_completion(call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, struct iatt *buf, -                         dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0) { -        gf_log(this->name, GF_LOG_WARNING, "stat failed (%d)", op_errno); -        goto error; -    } -    local->buf = *buf; -    STACK_WIND(frame, load_file_size, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->getxattr, local->loc, -               FSIZE_XATTR_PREFIX, NULL); -    return 0; -error: -    CRYPT_STACK_UNWIND(readv, frame, op_ret, op_errno, NULL, 0, NULL, NULL, -                       NULL); -    return 0; -} - -int32_t -crypt_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -            off_t offset, uint32_t flags, dict_t *xdata) -{ -    int32_t ret; -    crypt_local_t *local; -    struct crypt_inode_info *info; -    struct gf_flock lock = { -        0, -    }; - -#if DEBUG_CRYPT -    gf_log("crypt", GF_LOG_DEBUG, "reading %d bytes from offset %llu", -           (int)size, (long long)offset); -    if (parent_is_crypt_xlator(frame, this)) -        gf_log("crypt", GF_LOG_DEBUG, "parent is crypt"); -#endif -    local = crypt_alloc_local(frame, this, GF_FOP_READ); -    if (!local) { -        ret = ENOMEM; -        goto error; -    } -    if (size == 0) -        goto trivial; - -    local->fd = fd_ref(fd); -    local->flags = flags; - -    info = local_get_inode_info(local, this); -    if (info == NULL) { -        ret = EINVAL; -        fd_unref(fd); -        goto error; -    } -    if (!object_alg_atomic(&info->cinfo)) { -        ret = EINVAL; -        fd_unref(fd); -        goto error; -    } -    set_config_offsets(frame, this, offset, size, DATA_ATOM, 0); -    if (parent_is_crypt_xlator(frame, this)) { -        data_t *data; -        /* -         * We are called by crypt_writev (or cypt_ftruncate) -         * to perform the "read" component of the read-modify-write -         * (or read-prune-write) sequence for some atom; -         * -         * don't ask for access: -         * it has already been acquired -         * -         * Retrieve current file size -         */ -        if (!xdata) { -            gf_log("crypt", GF_LOG_WARNING, -                   "Regular file size hasn't been passed"); -            ret = EIO; -            goto error; -        } -        data = dict_get(xdata, FSIZE_XATTR_PREFIX); -        if (!data) { -            gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -            ret = EIO; -            goto error; -        } -        local->old_file_size = local->cur_file_size = data_to_uint64(data); - -        get_one_call(frame); -        STACK_WIND(frame, crypt_readv_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->readv, local->fd, -                   /* -                    * FIXME: read amount can be reduced -                    */ -                   local->data_conf.expanded_size, -                   local->data_conf.aligned_offset, flags, NULL); -        return 0; -    } -    if (xdata) -        local->xdata = dict_ref(xdata); - -    lock.l_len = 0; -    lock.l_start = 0; -    lock.l_type = F_RDLCK; -    lock.l_whence = SEEK_SET; - -    STACK_WIND(frame, crypt_readv_finodelk_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, -               &lock, NULL); -    return 0; -trivial: -    STACK_WIND(frame, readv_trivial_completion, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fstat, fd, NULL); -    return 0; -error: -    CRYPT_STACK_UNWIND(readv, frame, -1, ret, NULL, 0, NULL, NULL, NULL); -    return 0; -} - -void -set_local_io_params_writev(call_frame_t *frame, -                           struct object_cipher_info *object, -                           struct rmw_atom *atom, off_t io_offset, -                           uint32_t io_size) -{ -    crypt_local_t *local = frame->local; - -    local->io_offset = io_offset; -    local->io_size = io_size; - -    local->io_offset_nopad = atom->offset_at(frame, object) + -                             atom->offset_in(frame, object); - -    gf_log("crypt", GF_LOG_DEBUG, "set nopad offset to %llu", -           (unsigned long long)local->io_offset_nopad); - -    local->io_size_nopad = atom->io_size_nopad(frame, object); - -    gf_log("crypt", GF_LOG_DEBUG, "set nopad size to %llu", -           (unsigned long long)local->io_size_nopad); - -    local->update_disk_file_size = 0; -    /* -     * NOTE: eof_padding_size is 0 for all full atoms; -     * For head and tail atoms it will be set up at rmw_partial block() -     */ -    local->new_file_size = local->cur_file_size; - -    if (local->io_offset_nopad + local->io_size_nopad > local->cur_file_size) { -        local->new_file_size = local->io_offset_nopad + local->io_size_nopad; - -        gf_log("crypt", GF_LOG_DEBUG, "set new file size to %llu", -               (unsigned long long)local->new_file_size); - -        local->update_disk_file_size = 1; -    } -} - -void -set_local_io_params_ftruncate(call_frame_t *frame, -                              struct object_cipher_info *object) -{ -    uint32_t resid; -    crypt_local_t *local = frame->local; -    struct avec_config *conf = &local->data_conf; - -    resid = conf->orig_offset & (object_alg_blksize(object) - 1); -    if (resid) { -        local->eof_padding_size = object_alg_blksize(object) - resid; -        local->new_file_size = conf->aligned_offset; -        local->update_disk_file_size = 0; -        /* -         * file size will be updated -         * in the ->writev() stack, -         * when submitting file tail -         */ -    } else { -        local->eof_padding_size = 0; -        local->new_file_size = conf->orig_offset; -        local->update_disk_file_size = 1; -        /* -         * file size will be updated -         * in this ->ftruncate stack -         */ -    } -} - -static void -submit_head(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; -    submit_partial(frame, this, local->fd, HEAD_ATOM); -} - -static void -submit_tail(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; -    submit_partial(frame, this, local->fd, TAIL_ATOM); -} - -static void -submit_hole(call_frame_t *frame, xlator_t *this) -{ -    /* -     * hole conversion always means -     * appended write and goes in ordered fashion -     */ -    do_ordered_submit(frame, this, HOLE_ATOM); -} - -static void -submit_data(call_frame_t *frame, xlator_t *this) -{ -    if (is_ordered_mode(frame)) { -        do_ordered_submit(frame, this, DATA_ATOM); -        return; -    } -    gf_log("crypt", GF_LOG_WARNING, "Bad submit mode"); -    get_nr_calls(frame, nr_calls_data(frame)); -    do_parallel_submit(frame, this, DATA_ATOM); -    return; -} - -/* - * heplers called by writev_cbk, fruncate_cbk in ordered mode - */ - -static int32_t -should_submit_hole(crypt_local_t *local) -{ -    struct avec_config *conf = &local->hole_conf; - -    return conf->avec != NULL; -} - -static int32_t -should_resume_submit_hole(crypt_local_t *local) -{ -    struct avec_config *conf = &local->hole_conf; - -    if (local->fop == GF_FOP_WRITE && has_tail_block(conf)) -        /* -         * Don't submit a part of hole, which -         * fits into a data block: -         * this part of hole will be converted -         * as a gap filled by zeros in data head -         * block. -         */ -        return conf->cursor < conf->acount - 1; -    else -        return conf->cursor < conf->acount; -} - -static int32_t -should_resume_submit_data(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; -    struct avec_config *conf = &local->data_conf; - -    if (is_ordered_mode(frame)) -        return conf->cursor < conf->acount; -    /* -     * parallel writes -     */ -    return 0; -} - -static int32_t -should_submit_data_after_hole(crypt_local_t *local) -{ -    return local->data_conf.avec != NULL; -} - -static void -update_local_file_params(call_frame_t *frame, xlator_t *this, -                         struct iatt *prebuf, struct iatt *postbuf) -{ -    crypt_local_t *local = frame->local; - -    check_buf(frame, this, postbuf); - -    local->prebuf = *prebuf; -    local->postbuf = *postbuf; - -    local->prebuf.ia_size = local->cur_file_size; -    local->postbuf.ia_size = local->new_file_size; - -    local->cur_file_size = local->new_file_size; -} - -static int32_t -end_writeback_writev(call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                     struct iatt *postbuf, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret <= 0) { -        gf_log(this->name, GF_LOG_WARNING, "writev iteration failed"); -        goto put_one_call; -    } -    /* -     * op_ret includes paddings (atom's head, atom's tail and EOF) -     */ -    if (op_ret < local->io_size) { -        gf_log(this->name, GF_LOG_WARNING, "Incomplete writev iteration"); -        goto put_one_call; -    } -    op_ret -= local->eof_padding_size; -    local->op_ret = op_ret; - -    update_local_file_params(frame, this, prebuf, postbuf); - -    if (data_write_in_progress(local)) { -        LOCK(&local->rw_count_lock); -        local->rw_count += op_ret; -        UNLOCK(&local->rw_count_lock); - -        if (should_resume_submit_data(frame)) -            submit_data(frame, this); -    } else { -        /* -         * hole conversion is going on; -         * don't take into account written zeros -         */ -        if (should_resume_submit_hole(local)) -            submit_hole(frame, this); - -        else if (should_submit_data_after_hole(local)) -            submit_data(frame, this); -    } -put_one_call: -    put_one_call_writev(frame, this); -    return 0; -} - -#define crypt_writev_cbk end_writeback_writev - -#define HOLE_WRITE_CHUNK_BITS 12 -#define HOLE_WRITE_CHUNK_SIZE (1 << HOLE_WRITE_CHUNK_BITS) - -/* - * Convert hole of size @size at offset @off to - * zeros and prepare respective iovecs for submit. - * The hole lock should be held. - * - * Pre-conditions: - * @local->file_size is set and valid. - */ -int32_t -prepare_for_submit_hole(call_frame_t *frame, xlator_t *this, uint64_t off, -                        off_t size) -{ -    int32_t ret; -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = &local->info->cinfo; - -    set_config_offsets(frame, this, off, size, HOLE_ATOM, 1); - -    ret = set_config_avec_hole(this, local, &local->hole_conf, object, -                               local->fop); -    crypt_check_conf(&local->hole_conf); - -    return ret; -} - -/* - * prepare for submit @count bytes at offset @from - */ -int32_t -prepare_for_submit_data(call_frame_t *frame, xlator_t *this, off_t from, -                        int32_t size, struct iovec *vec, int32_t vec_count, -                        int32_t setup_gap) -{ -    uint32_t ret; -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = &local->info->cinfo; - -    set_config_offsets(frame, this, from, size, DATA_ATOM, setup_gap); - -    ret = set_config_avec_data(this, local, &local->data_conf, object, vec, -                               vec_count); -    crypt_check_conf(&local->data_conf); - -    return ret; -} - -static void -free_avec(struct iovec *avec, char **pool, int blocks_in_pool) -{ -    if (!avec) -        return; -    GF_FREE(pool); -    GF_FREE(avec); -} - -static void -free_avec_data(crypt_local_t *local) -{ -    return free_avec(local->data_conf.avec, local->data_conf.pool, -                     local->data_conf.blocks_in_pool); -} - -static void -free_avec_hole(crypt_local_t *local) -{ -    return free_avec(local->hole_conf.avec, local->hole_conf.pool, -                     local->hole_conf.blocks_in_pool); -} - -static void -do_parallel_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype) -{ -    crypt_local_t *local = frame->local; -    struct avec_config *conf; - -    local->active_setup = dtype; -    conf = conf_by_type(frame, dtype); - -    if (has_head_block(conf)) -        submit_head(frame, this); - -    if (has_full_blocks(conf)) -        submit_full(frame, this); - -    if (has_tail_block(conf)) -        submit_tail(frame, this); -    return; -} - -static void -do_ordered_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype) -{ -    crypt_local_t *local = frame->local; -    struct avec_config *conf; - -    local->active_setup = dtype; -    conf = conf_by_type(frame, dtype); - -    if (should_submit_head_block(conf)) { -        get_one_call_nolock(frame); -        submit_head(frame, this); -    } else if (should_submit_full_block(conf)) { -        get_one_call_nolock(frame); -        submit_full(frame, this); -    } else if (should_submit_tail_block(conf)) { -        get_one_call_nolock(frame); -        submit_tail(frame, this); -    } else -        gf_log("crypt", GF_LOG_DEBUG, -               "nothing has been submitted in ordered mode"); -    return; -} - -static int32_t -do_writev(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -          int32_t op_errno, dict_t *dict, dict_t *xdata) -{ -    data_t *data; -    crypt_local_t *local = frame->local; -    struct object_cipher_info *object = &local->info->cinfo; -    /* -     * extract regular file size -     */ -    data = dict_get(dict, FSIZE_XATTR_PREFIX); -    if (!data) { -        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -        op_ret = -1; -        op_errno = EIO; -        goto error; -    } -    local->old_file_size = local->cur_file_size = data_to_uint64(data); - -    set_gap_at_end(frame, object, &local->data_conf, DATA_ATOM); - -    if (local->cur_file_size < local->data_conf.orig_offset) { -        /* -         * Set up hole config -         */ -        op_errno = prepare_for_submit_hole( -            frame, this, local->cur_file_size, -            local->data_conf.orig_offset - local->cur_file_size); -        if (op_errno) { -            local->op_ret = -1; -            local->op_errno = op_errno; -            goto error; -        } -    } -    if (should_submit_hole(local)) -        submit_hole(frame, this); -    else -        submit_data(frame, this); -    return 0; -error: -    get_one_call_nolock(frame); -    put_one_call_writev(frame, this); -    return 0; -} - -static int32_t -crypt_writev_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                          int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0) -        goto error; -    /* -     * An access has been granted, -     * retrieve file size first -     */ -    STACK_WIND(frame, do_writev, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fgetxattr, local->fd, -               FSIZE_XATTR_PREFIX, NULL); -    return 0; -error: -    get_one_call_nolock(frame); -    put_one_call_writev(frame, this); -    return 0; -} - -static int32_t -writev_trivial_completion(call_frame_t *frame, void *cookie, xlator_t *this, -                          int32_t op_ret, int32_t op_errno, struct iatt *buf, -                          dict_t *dict) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; -    local->prebuf = *buf; -    local->postbuf = *buf; - -    local->prebuf.ia_size = local->cur_file_size; -    local->postbuf.ia_size = local->cur_file_size; - -    get_one_call(frame); -    put_one_call_writev(frame, this); -    return 0; -} - -int -crypt_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vec, -             int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, -             dict_t *xdata) -{ -    int32_t ret; -    crypt_local_t *local; -    struct crypt_inode_info *info; -    struct gf_flock lock = { -        0, -    }; -#if DEBUG_CRYPT -    gf_log("crypt", GF_LOG_DEBUG, "writing %d bytes from offset %llu", -           (int)iov_length(vec, count), (long long)offset); -#endif -    local = crypt_alloc_local(frame, this, GF_FOP_WRITE); -    if (!local) { -        ret = ENOMEM; -        goto error; -    } -    local->fd = fd_ref(fd); - -    if (iobref) -        local->iobref = iobref_ref(iobref); -    /* -     * to update real file size on the server -     */ -    local->xattr = dict_new(); -    if (!local->xattr) { -        ret = ENOMEM; -        goto error; -    } -    local->flags = flags; - -    info = local_get_inode_info(local, this); -    if (info == NULL) { -        ret = EINVAL; -        goto error; -    } -    if (!object_alg_atomic(&info->cinfo)) { -        ret = EINVAL; -        goto error; -    } -    if (iov_length(vec, count) == 0) -        goto trivial; - -    ret = prepare_for_submit_data(frame, this, offset, -				      iov_length(vec, count), -				      vec, count, 0 /* don't setup gup -						       in tail: we don't -						       know file size yet */); -    if (ret) { -        ret = ENOMEM; -        goto error; -    } - -    if (parent_is_crypt_xlator(frame, this)) { -        data_t *data; -        /* -         * we are called by shinking crypt_ftruncate(), -         * which doesn't perform hole conversion; -         * -         * don't ask for access: -         * it has already been acquired -         */ - -        /* -         * extract file size -         */ -        if (!xdata) { -            gf_log("crypt", GF_LOG_WARNING, -                   "Regular file size hasn't been passed"); -            ret = EIO; -            goto error; -        } -        data = dict_get(xdata, FSIZE_XATTR_PREFIX); -        if (!data) { -            gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -            ret = EIO; -            goto error; -        } -        local->old_file_size = local->cur_file_size = data_to_uint64(data); - -        submit_data(frame, this); -        return 0; -    } -    if (xdata) -        local->xdata = dict_ref(xdata); -    /* -     * lock the file and retrieve its size -     */ -    lock.l_len = 0; -    lock.l_start = 0; -    lock.l_type = F_WRLCK; -    lock.l_whence = SEEK_SET; - -    STACK_WIND(frame, crypt_writev_finodelk_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, -               &lock, NULL); -    return 0; -trivial: -    STACK_WIND(frame, writev_trivial_completion, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fstat, fd, NULL); -    return 0; -error: -    if (local && local->fd) -        fd_unref(fd); -    if (local && local->iobref) -        iobref_unref(iobref); -    if (local && local->xdata) -        dict_unref(xdata); -    if (local && local->xattr) -        dict_unref(local->xattr); -    if (local && local->info) -        free_inode_info(local->info); - -    CRYPT_STACK_UNWIND(writev, frame, -1, ret, NULL, NULL, NULL); -    return 0; -} - -int32_t -prepare_for_prune(call_frame_t *frame, xlator_t *this, uint64_t offset) -{ -    set_config_offsets(frame, this, -			   offset, -			   0, /* count */ -			   DATA_ATOM, -			   0 /* since we prune, there is no -				gap in tail to uptodate */); -    return 0; -} - -/* - * Finish the read-prune-modify sequence - * - * Can be invoked as - * 1) ->ftruncate_cbk() for cblock-aligned, or trivial prune - * 2) ->writev_cbk() for non-cblock-aligned prune - */ - -static int32_t -prune_complete(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -               struct iatt *postbuf, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    update_local_file_params(frame, this, prebuf, postbuf); - -    put_one_call_ftruncate(frame, this); -    return 0; -} - -/* - * This is called as ->ftruncate_cbk() - * - * Perform the "write" component of the - * read-prune-write sequence. - * - * submuit the rest of the file - */ -static int32_t -prune_submit_file_tail(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                       struct iatt *postbuf, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    struct avec_config *conf = &local->data_conf; -    dict_t *dict; - -    if (op_ret < 0) -        goto put_one_call; - -    if (local->xdata) { -        dict_unref(local->xdata); -        local->xdata = NULL; -    } -    if (xdata) -        local->xdata = dict_ref(xdata); - -    dict = dict_new(); -    if (!dict) { -        op_errno = ENOMEM; -        goto error; -    } - -    update_local_file_params(frame, this, prebuf, postbuf); -    local->new_file_size = conf->orig_offset; - -    /* -     * The rest of the file is a partial block and, hence, -     * should be written via RMW sequence, so the crypt xlator -     * does STACK_WIND to itself. -     * -     * Pass current file size to crypt_writev() -     */ -    op_errno = dict_set(dict, FSIZE_XATTR_PREFIX, -                        data_from_uint64(local->cur_file_size)); -    if (op_errno) { -        gf_log("crypt", GF_LOG_WARNING, "can not set key to update file size"); -        dict_unref(dict); -        goto error; -    } -    gf_log("crypt", GF_LOG_DEBUG, -           "passing current file size (%llu) to crypt_writev", -           (unsigned long long)local->cur_file_size); -    /* -     * Padding will be filled with -     * zeros by rmw_partial_block() -     */ -    STACK_WIND(frame, prune_complete, this, -               this->fops->writev, /* crypt_writev */ -               local->fd, &local->vec, 1, -               conf->aligned_offset, /* offset to write from */ -               0, local->iobref, dict); - -    dict_unref(dict); -    return 0; -error: -    local->op_ret = -1; -    local->op_errno = op_errno; -put_one_call: -    put_one_call_ftruncate(frame, this); -    return 0; -} - -/* - * This is called as a callback of ->writev() invoked in behalf - * of ftruncate(): it can be - * 1) ordered writes issued by hole conversion in the case of - *    expanded truncate, or - * 2) an rmw partial data block issued by non-cblock-aligned - * prune. - */ -int32_t -end_writeback_ftruncate(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                        struct iatt *postbuf, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    /* -     * if nothing has been written, -     * then it must be an error -     */ -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0) -        goto put_one_call; - -    update_local_file_params(frame, this, prebuf, postbuf); - -    if (data_write_in_progress(local)) -        /* case (2) */ -        goto put_one_call; -    /* case (1) */ -    if (should_resume_submit_hole(local)) -        submit_hole(frame, this); -    /* -     * case of hole, when we shouldn't resume -     */ -put_one_call: -    put_one_call_ftruncate(frame, this); -    return 0; -} - -/* - * Perform prune and write components of the - * read-prune-write sequence. - * - * Called as ->readv_cbk() - * - * Pre-conditions: - * @vec contains the latest atom of the file - * (plain text) - */ -static int32_t -prune_write(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -            int32_t op_errno, struct iovec *vec, int32_t count, -            struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) -{ -    int32_t i; -    size_t to_copy; -    size_t copied = 0; -    crypt_local_t *local = frame->local; -    struct avec_config *conf = &local->data_conf; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; -    if (op_ret == -1) -        goto put_one_call; - -    /* -     * At first, uptodate head block -     */ -    if (iov_length(vec, count) < conf->off_in_head) { -        gf_log(this->name, GF_LOG_WARNING, -               "Failed to uptodate head block for prune"); -        local->op_ret = -1; -        local->op_errno = EIO; -        goto put_one_call; -    } -    local->vec.iov_len = conf->off_in_head; -    local->vec.iov_base = GF_CALLOC(1, local->vec.iov_len, gf_crypt_mt_data); - -    if (local->vec.iov_base == NULL) { -        gf_log(this->name, GF_LOG_WARNING, -               "Failed to calloc head block for prune"); -        local->op_ret = -1; -        local->op_errno = ENOMEM; -        goto put_one_call; -    } -    for (i = 0; i < count; i++) { -        to_copy = vec[i].iov_len; -        if (to_copy > local->vec.iov_len - copied) -            to_copy = local->vec.iov_len - copied; - -        memcpy((char *)local->vec.iov_base + copied, vec[i].iov_base, to_copy); -        copied += to_copy; -        if (copied == local->vec.iov_len) -            break; -    } -    /* -     * perform prune with aligned offset -     * (i.e. at this step we prune a bit -     * more then it is needed -     */ -    STACK_WIND(frame, prune_submit_file_tail, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->ftruncate, local->fd, -               conf->aligned_offset, local->xdata); -    return 0; -put_one_call: -    put_one_call_ftruncate(frame, this); -    return 0; -} - -/* - * Perform a read-prune-write sequence - */ -int32_t -read_prune_write(call_frame_t *frame, xlator_t *this) -{ -    int32_t ret = 0; -    dict_t *dict = NULL; -    crypt_local_t *local = frame->local; -    struct avec_config *conf = &local->data_conf; -    struct object_cipher_info *object = &local->info->cinfo; - -    set_local_io_params_ftruncate(frame, object); -    get_one_call_nolock(frame); - -    if ((conf->orig_offset & (object_alg_blksize(object) - 1)) == 0) { -        /* -         * cblock-aligned prune: -         * we don't need read and write components, -         * just cut file body -         */ -        gf_log("crypt", GF_LOG_DEBUG, "prune without RMW (at offset %llu", -               (unsigned long long)conf->orig_offset); - -        STACK_WIND(frame, prune_complete, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->ftruncate, local->fd, -                   conf->orig_offset, local->xdata); -        return 0; -    } -    gf_log("crypt", GF_LOG_DEBUG, "prune with RMW (at offset %llu", -           (unsigned long long)conf->orig_offset); -    /* -     * We are about to perform the "read" component of the -     * read-prune-write sequence. It means that we need to -     * read encrypted data from disk and decrypt it. -     * So, the crypt translator does STACK_WIND to itself. -     * -     * Pass current file size to crypt_readv() - -     */ -    dict = dict_new(); -    if (!dict) { -        gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict"); -        ret = ENOMEM; -        goto exit; -    } -    ret = dict_set(dict, FSIZE_XATTR_PREFIX, -                   data_from_uint64(local->cur_file_size)); -    if (ret) { -        gf_log("crypt", GF_LOG_WARNING, "Can not set dict"); -        goto exit; -    } -    STACK_WIND(frame, prune_write, this, this->fops->readv, /* crypt_readv */ -               local->fd, get_atom_size(object),            /* bytes to read */ -               conf->aligned_offset, /* offset to read from */ -               0, dict); -exit: -    if (dict) -        dict_unref(dict); -    return ret; -} - -/* - * File prune is more complicated than expand. - * First we need to read the latest atom to not lose info - * needed for proper update. Also we need to make sure that - * every component of read-prune-write sequence leaves data - * consistent - * - * Non-cblock aligned prune is performed as read-prune-write - * sequence: - * - * 1) read the latest atom; - * 2) perform cblock-aligned prune - * 3) issue a write request for the end-of-file - */ -int32_t -prune_file(call_frame_t *frame, xlator_t *this, uint64_t offset) -{ -    int32_t ret; - -    ret = prepare_for_prune(frame, this, offset); -    if (ret) -        return ret; -    return read_prune_write(frame, this); -} - -int32_t -expand_file(call_frame_t *frame, xlator_t *this, uint64_t offset) -{ -    int32_t ret; -    crypt_local_t *local = frame->local; - -    ret = prepare_for_submit_hole(frame, this, local->old_file_size, -                                  offset - local->old_file_size); -    if (ret) -        return ret; -    submit_hole(frame, this); -    return 0; -} - -static int32_t -ftruncate_trivial_completion(call_frame_t *frame, void *cookie, xlator_t *this, -                             int32_t op_ret, int32_t op_errno, struct iatt *buf, -                             dict_t *dict) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; -    local->prebuf = *buf; -    local->postbuf = *buf; - -    local->prebuf.ia_size = local->cur_file_size; -    local->postbuf.ia_size = local->cur_file_size; - -    get_one_call(frame); -    put_one_call_ftruncate(frame, this); -    return 0; -} - -static int32_t -do_ftruncate(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, dict_t *dict, dict_t *xdata) -{ -    data_t *data; -    crypt_local_t *local = frame->local; - -    if (op_ret) -        goto error; -    /* -     * extract regular file size -     */ -    data = dict_get(dict, FSIZE_XATTR_PREFIX); -    if (!data) { -        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -        op_errno = EIO; -        goto error; -    } -    local->old_file_size = local->cur_file_size = data_to_uint64(data); - -    if (local->data_conf.orig_offset == local->cur_file_size) { -#if DEBUG_CRYPT -        gf_log("crypt", GF_LOG_DEBUG, -               "trivial ftruncate (current file size %llu)", -               (unsigned long long)local->cur_file_size); -#endif -        goto trivial; -    } else if (local->data_conf.orig_offset < local->cur_file_size) { -#if DEBUG_CRYPT -        gf_log("crypt", GF_LOG_DEBUG, "prune from %llu to %llu", -               (unsigned long long)local->cur_file_size, -               (unsigned long long)local->data_conf.orig_offset); -#endif -        op_errno = prune_file(frame, this, local->data_conf.orig_offset); -    } else { -#if DEBUG_CRYPT -        gf_log("crypt", GF_LOG_DEBUG, "expand from %llu to %llu", -               (unsigned long long)local->cur_file_size, -               (unsigned long long)local->data_conf.orig_offset); -#endif -        op_errno = expand_file(frame, this, local->data_conf.orig_offset); -    } -    if (op_errno) -        goto error; -    return 0; -trivial: -    STACK_WIND(frame, ftruncate_trivial_completion, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fstat, local->fd, NULL); -    return 0; -error: -    /* -     * finish with ftruncate -     */ -    local->op_ret = -1; -    local->op_errno = op_errno; - -    get_one_call_nolock(frame); -    put_one_call_ftruncate(frame, this); -    return 0; -} - -static int32_t -crypt_ftruncate_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                             int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0) -        goto error; -    /* -     * An access has been granted, -     * retrieve file size first -     */ -    STACK_WIND(frame, do_ftruncate, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fgetxattr, local->fd, -               FSIZE_XATTR_PREFIX, NULL); -    return 0; -error: -    get_one_call_nolock(frame); -    put_one_call_ftruncate(frame, this); -    return 0; -} - -/* - * ftruncate is performed in 2 steps: - * . receive file size; - * . expand or prune file. - */ -static int32_t -crypt_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -                dict_t *xdata) -{ -    int32_t ret; -    crypt_local_t *local; -    struct crypt_inode_info *info; -    struct gf_flock lock = { -        0, -    }; - -    local = crypt_alloc_local(frame, this, GF_FOP_FTRUNCATE); -    if (!local) { -        ret = ENOMEM; -        goto error; -    } -    local->xattr = dict_new(); -    if (!local->xattr) { -        ret = ENOMEM; -        goto error; -    } -    local->fd = fd_ref(fd); -    info = local_get_inode_info(local, this); -    if (info == NULL) { -        ret = EINVAL; -        goto error; -    } -    if (!object_alg_atomic(&info->cinfo)) { -        ret = EINVAL; -        goto error; -    } -    local->data_conf.orig_offset = offset; -    if (xdata) -        local->xdata = dict_ref(xdata); - -    lock.l_len = 0; -    lock.l_start = 0; -    lock.l_type = F_WRLCK; -    lock.l_whence = SEEK_SET; - -    STACK_WIND(frame, crypt_ftruncate_finodelk_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, -               &lock, NULL); -    return 0; -error: -    if (local && local->fd) -        fd_unref(fd); -    if (local && local->xdata) -        dict_unref(xdata); -    if (local && local->xattr) -        dict_unref(local->xattr); -    if (local && local->info) -        free_inode_info(local->info); - -    CRYPT_STACK_UNWIND(ftruncate, frame, -1, ret, NULL, NULL, NULL); -    return 0; -} - -/* ->flush_cbk() */ -int32_t -truncate_end(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    CRYPT_STACK_UNWIND(truncate, frame, op_ret, op_errno, &local->prebuf, -                       &local->postbuf, local->xdata); -    return 0; -} - -/* ftruncate_cbk() */ -int32_t -truncate_flush(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -               struct iatt *postbuf, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    fd_t *fd = local->fd; -    local->prebuf = *prebuf; -    local->postbuf = *postbuf; - -    STACK_WIND(frame, truncate_end, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->flush, fd, NULL); -    fd_unref(fd); -    return 0; -} - -/* - * is called as ->open_cbk() - */ -static int32_t -truncate_begin(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) { -        fd_unref(fd); -        CRYPT_STACK_UNWIND(truncate, frame, op_ret, op_errno, NULL, NULL, NULL); -        return 0; -    } else { -        fd_bind(fd); -    } -    /* -     * crypt_truncate() is implemented via crypt_ftruncate(), -     * so the crypt xlator does STACK_WIND to itself here -     */ -    STACK_WIND(frame, truncate_flush, this, -               this->fops->ftruncate, /* crypt_ftruncate */ -               fd, local->offset, NULL); -    return 0; -} - -/* - * crypt_truncate() is implemented via crypt_ftruncate() as a - * sequence crypt_open() - crypt_ftruncate() - truncate_flush() - */ -int32_t -crypt_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, -               dict_t *xdata) -{ -    fd_t *fd; -    crypt_local_t *local; - -#if DEBUG_CRYPT -    gf_log(this->name, GF_LOG_DEBUG, "truncate file %s at offset %llu", -           loc->path, (unsigned long long)offset); -#endif -    local = crypt_alloc_local(frame, this, GF_FOP_TRUNCATE); -    if (!local) -        goto error; - -    fd = fd_create(loc->inode, frame->root->pid); -    if (!fd) { -        gf_log(this->name, GF_LOG_ERROR, "Can not create fd"); -        goto error; -    } -    local->fd = fd; -    local->offset = offset; -    local->xdata = xdata; -    STACK_WIND(frame, truncate_begin, this, this->fops->open, /* crypt_open() */ -               loc, O_RDWR, fd, NULL); -    return 0; -error: -    CRYPT_STACK_UNWIND(truncate, frame, -1, EINVAL, NULL, NULL, NULL); -    return 0; -} - -end_writeback_handler_t -dispatch_end_writeback(glusterfs_fop_t fop) -{ -    switch (fop) { -        case GF_FOP_WRITE: -            return end_writeback_writev; -        case GF_FOP_FTRUNCATE: -            return end_writeback_ftruncate; -        default: -            gf_log("crypt", GF_LOG_WARNING, "Bad wb operation %d", fop); -            return NULL; -    } -} - -/* - * true, if the caller needs metadata string - */ -static int32_t -is_custom_mtd(dict_t *xdata) -{ -    data_t *data; -    uint32_t flags; - -    if (!xdata) -        return 0; - -    data = dict_get(xdata, MSGFLAGS_PREFIX); -    if (!data) -        return 0; -    if (data->len != sizeof(uint32_t)) { -        gf_log("crypt", GF_LOG_WARNING, "Bad msgflags size (%d)", data->len); -        return -1; -    } -    flags = *((uint32_t *)data->data); -    return msgflags_check_mtd_lock(&flags); -} - -static int32_t -crypt_open_done(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; -    if (op_ret < 0) -        gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)", op_errno); -    put_one_call_open(frame); -    return 0; -} - -static void -crypt_open_tail(call_frame_t *frame, xlator_t *this) -{ -    struct gf_flock lock = { -        0, -    }; -    crypt_local_t *local = frame->local; - -    lock.l_type = F_UNLCK; -    lock.l_whence = SEEK_SET; -    lock.l_start = 0; -    lock.l_len = 0; -    lock.l_pid = 0; - -    STACK_WIND(frame, crypt_open_done, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, -               F_SETLKW, &lock, NULL); -} - -/* - * load private inode info at open time - * called as ->fgetxattr_cbk() - */ -static int -load_mtd_open(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, dict_t *dict, dict_t *xdata) -{ -    int32_t ret; -    gf_boolean_t upload_info; -    data_t *mtd; -    uint64_t value = 0; -    struct crypt_inode_info *info; -    crypt_local_t *local = frame->local; -    crypt_private_t *priv = this->private; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (local->fd->inode->ia_type == IA_IFLNK) -        goto exit; -    if (op_ret < 0) -        goto exit; -    /* -     * first, check for cached info -     */ -    ret = inode_ctx_get(local->fd->inode, this, &value); -    if (ret != -1) { -        info = (struct crypt_inode_info *)(long)value; -        if (info == NULL) { -            gf_log(this->name, GF_LOG_WARNING, -                   "Inode info expected, but not found"); -            local->op_ret = -1; -            local->op_errno = EIO; -            goto exit; -        } -        /* -         * info has been found in the cache -         */ -        upload_info = _gf_false; -    } else { -        /* -         * info hasn't been found in the cache. -         */ -        info = alloc_inode_info(local, local->loc); -        if (!info) { -            local->op_ret = -1; -            local->op_errno = ENOMEM; -            goto exit; -        } -        init_inode_info_head(info, local->fd); -        upload_info = _gf_true; -    } -    /* -     * extract metadata -     */ -    mtd = dict_get(dict, CRYPTO_FORMAT_PREFIX); -    if (!mtd) { -        local->op_ret = -1; -        local->op_errno = ENOENT; -        gf_log(this->name, GF_LOG_WARNING, "Format string wasn't found"); -        goto exit; -    } -    /* -     * authenticate metadata against the path -     */ -    ret = open_format((unsigned char *)mtd->data, mtd->len, local->loc, info, -                      get_master_cinfo(priv), local, upload_info); -    if (ret) { -        local->op_ret = -1; -        local->op_errno = ret; -        goto exit; -    } -    if (upload_info) { -        ret = init_inode_info_tail(info, get_master_cinfo(priv)); -        if (ret) { -            local->op_ret = -1; -            local->op_errno = ret; -            goto exit; -        } -        ret = inode_ctx_put(local->fd->inode, this, (uint64_t)(long)info); -        if (ret == -1) { -            local->op_ret = -1; -            local->op_errno = EIO; -            goto exit; -        } -    } -    if (local->custom_mtd) { -        /* -         * pass the metadata string to the customer -         */ -        ret = dict_set_static_bin(local->xdata, CRYPTO_FORMAT_PREFIX, mtd->data, -                                  mtd->len); -        if (ret) { -            local->op_ret = -1; -            local->op_errno = ret; -            goto exit; -        } -    } -exit: -    if (!local->custom_mtd) -        crypt_open_tail(frame, this); -    else -        put_one_call_open(frame); -    return 0; -} - -static int32_t -crypt_open_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0) { -        gf_log(this->name, GF_LOG_WARNING, "finodelk (LOCK) failed"); -        goto exit; -    } -    STACK_WIND(frame, load_mtd_open, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fgetxattr, local->fd, -               CRYPTO_FORMAT_PREFIX, NULL); -    return 0; -exit: -    put_one_call_open(frame); -    return 0; -} - -/* - * verify metadata against the specified pathname - */ -static int32_t -crypt_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    struct gf_flock lock = { -        0, -    }; -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (local->fd->inode->ia_type == IA_IFLNK) -        goto exit; -    if (op_ret < 0) -        goto exit; -    if (xdata) -        local->xdata = dict_ref(xdata); -    else if (local->custom_mtd) { -        local->xdata = dict_new(); -        if (!local->xdata) { -            local->op_ret = -1; -            local->op_errno = ENOMEM; -            gf_log("crypt", GF_LOG_ERROR, -                   "Can not get new dict for mtd string"); -            goto exit; -        } -    } -    lock.l_len = 0; -    lock.l_start = 0; -    lock.l_type = local->custom_mtd ? F_WRLCK : F_RDLCK; -    lock.l_whence = SEEK_SET; - -    STACK_WIND(frame, crypt_open_finodelk_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, -               &lock, NULL); -    return 0; -exit: -    put_one_call_open(frame); -    return 0; -} - -static int32_t -crypt_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -           fd_t *fd, dict_t *xdata) -{ -    int32_t ret = ENOMEM; -    crypt_local_t *local; - -    local = crypt_alloc_local(frame, this, GF_FOP_OPEN); -    if (!local) -        goto error; -    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -    if (!local->loc) { -        ret = ENOMEM; -        goto error; -    } -    ret = loc_copy(local->loc, loc); -    if (ret) { -        GF_FREE(local->loc); -        ret = ENOMEM; -        goto error; -    } -    local->fd = fd_ref(fd); - -    ret = is_custom_mtd(xdata); -    if (ret < 0) { -        loc_wipe(local->loc); -        GF_FREE(local->loc); -        ret = EINVAL; -        goto error; -    } -    local->custom_mtd = ret; - -    if ((flags & O_ACCMODE) == O_WRONLY) -        /* -         * we can't open O_WRONLY, because -         * we need to do read-modify-write -         */ -        flags = (flags & ~O_ACCMODE) | O_RDWR; -    /* -     * Make sure that out translated offsets -     * and counts won't be ignored -     */ -    flags &= ~O_APPEND; -    get_one_call_nolock(frame); -    STACK_WIND(frame, crypt_open_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); -    return 0; -error: -    CRYPT_STACK_UNWIND(open, frame, -1, ret, NULL, NULL); -    return 0; -} - -static int32_t -init_inode_info_tail(struct crypt_inode_info *info, -                     struct master_cipher_info *master) -{ -    int32_t ret; -    struct object_cipher_info *object = &info->cinfo; - -#if DEBUG_CRYPT -    gf_log("crypt", GF_LOG_DEBUG, "Init inode info for object %s", -           uuid_utoa(info->oid)); -#endif -    ret = data_cipher_algs[object->o_alg][object->o_mode].set_private(info, -                                                                      master); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, "Set private info failed"); -        return ret; -    } -    return 0; -} - -/* - * Init inode info at ->create() time - */ -static void -init_inode_info_create(struct crypt_inode_info *info, -                       struct master_cipher_info *master, data_t *data) -{ -    struct object_cipher_info *object; - -    info->nr_minor = CRYPT_XLATOR_ID; -    memcpy(info->oid, data->data, data->len); - -    object = &info->cinfo; - -    object->o_alg = master->m_alg; -    object->o_mode = master->m_mode; -    object->o_block_bits = master->m_block_bits; -    object->o_dkey_size = master->m_dkey_size; -} - -static void -init_inode_info_head(struct crypt_inode_info *info, fd_t *fd) -{ -    memcpy(info->oid, fd->inode->gfid, sizeof(uuid_t)); -} - -static int32_t -crypt_create_done(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_private_t *priv = this->private; -    crypt_local_t *local = frame->local; -    struct crypt_inode_info *info = local->info; -    fd_t *local_fd = local->fd; -    dict_t *local_xdata = local->xdata; -    inode_t *local_inode = local->inode; - -    if (op_ret < 0) { -        free_inode_info(info); -        goto unwind; -    } -    op_errno = init_inode_info_tail(info, get_master_cinfo(priv)); -    if (op_errno) { -        op_ret = -1; -        free_inode_info(info); -        goto unwind; -    } -    /* -     * FIXME: drop major subversion number -     */ -    op_ret = inode_ctx_put(local->fd->inode, this, (uint64_t)(long)info); -    if (op_ret == -1) { -        op_errno = EIO; -        free_inode_info(info); -        goto unwind; -    } -unwind: -    free_format(local); -    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, local_fd, local_inode, -                       &local->buf, &local->prebuf, &local->postbuf, -                       local_xdata); -    fd_unref(local_fd); -    inode_unref(local_inode); -    if (local_xdata) -        dict_unref(local_xdata); -    return 0; -} - -static int -crypt_create_tail(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    struct gf_flock lock = { -        0, -    }; -    crypt_local_t *local = frame->local; -    fd_t *local_fd = local->fd; -    dict_t *local_xdata = local->xdata; -    inode_t *local_inode = local->inode; - -    dict_unref(local->xattr); - -    if (op_ret < 0) -        goto error; - -    lock.l_type = F_UNLCK; -    lock.l_whence = SEEK_SET; -    lock.l_start = 0; -    lock.l_len = 0; -    lock.l_pid = 0; - -    STACK_WIND(frame, crypt_create_done, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, -               F_SETLKW, &lock, NULL); -    return 0; -error: -    free_inode_info(local->info); -    free_format(local); - -    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, local_fd, local_inode, -                       &local->buf, &local->prebuf, &local->postbuf, -                       local_xdata); - -    fd_unref(local_fd); -    inode_unref(local_inode); -    if (local_xdata) -        dict_unref(local_xdata); -    return 0; -} - -static int32_t -crypt_create_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                          int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    struct crypt_inode_info *info = local->info; - -    if (op_ret < 0) -        goto error; - -    STACK_WIND(frame, crypt_create_tail, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsetxattr, local->fd, -               local->xattr, /* CRYPTO_FORMAT_PREFIX */ -               0, NULL); -    return 0; -error: -    free_inode_info(info); -    free_format(local); -    fd_unref(local->fd); -    dict_unref(local->xattr); -    if (local->xdata) -        dict_unref(local->xdata); - -    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, -                       NULL, NULL); -    return 0; -} - -/* - * Create and store crypt-specific format on disk; - * Populate cache with private inode info - */ -static int32_t -crypt_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, -                 struct iatt *buf, struct iatt *preparent, -                 struct iatt *postparent, dict_t *xdata) -{ -    struct gf_flock lock = { -        0, -    }; -    crypt_local_t *local = frame->local; -    struct crypt_inode_info *info = local->info; - -    if (op_ret < 0) -        goto error; -    if (xdata) -        local->xdata = dict_ref(xdata); -    local->inode = inode_ref(inode); -    local->buf = *buf; -    local->prebuf = *preparent; -    local->postbuf = *postparent; - -    lock.l_len = 0; -    lock.l_start = 0; -    lock.l_type = F_WRLCK; -    lock.l_whence = SEEK_SET; - -    STACK_WIND(frame, crypt_create_finodelk_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, -               F_SETLKW, &lock, NULL); -    return 0; -error: -    free_inode_info(info); -    free_format(local); -    fd_unref(local->fd); -    dict_unref(local->xattr); - -    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, -                       NULL, NULL); -    return 0; -} - -static int32_t -crypt_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -             mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) -{ -    int ret; -    data_t *data; -    crypt_local_t *local; -    crypt_private_t *priv; -    struct master_cipher_info *master; -    struct crypt_inode_info *info; - -    priv = this->private; -    master = get_master_cinfo(priv); - -    if (master_alg_atomic(master)) { -        /* -         * We can't open O_WRONLY, because we -         * need to do read-modify-write. -         */ -        if ((flags & O_ACCMODE) == O_WRONLY) -            flags = (flags & ~O_ACCMODE) | O_RDWR; -        /* -         * Make sure that out translated offsets -         * and counts won't be ignored -         */ -        flags &= ~O_APPEND; -    } -    local = crypt_alloc_local(frame, this, GF_FOP_CREATE); -    if (!local) { -        ret = ENOMEM; -        goto error; -    } -    data = dict_get(xdata, "gfid-req"); -    if (!data) { -        ret = EINVAL; -        gf_log("crypt", GF_LOG_WARNING, "gfid not found"); -        goto error; -    } -    if (data->len != sizeof(uuid_t)) { -        ret = EINVAL; -        gf_log("crypt", GF_LOG_WARNING, "bad gfid size (%d), should be %d", -               (int)data->len, (int)sizeof(uuid_t)); -        goto error; -    } -    info = alloc_inode_info(local, loc); -    if (!info) { -        ret = ENOMEM; -        goto error; -    } -    /* -     * NOTE: -     * format has to be created BEFORE -     * proceeding to the untrusted server -     */ -    ret = alloc_format_create(local); -    if (ret) { -        free_inode_info(info); -        goto error; -    } -    init_inode_info_create(info, master, data); - -    ret = create_format(local->format, loc, info, master); -    if (ret) { -        free_inode_info(info); -        goto error; -    } -    local->xattr = dict_new(); -    if (!local->xattr) { -        free_inode_info(info); -        free_format(local); -        goto error; -    } -    ret = dict_set_static_bin(local->xattr, CRYPTO_FORMAT_PREFIX, local->format, -                              new_format_size()); -    if (ret) { -        dict_unref(local->xattr); -        free_inode_info(info); -        free_format(local); -        ret = EINVAL; -        goto error; -    } -    ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, data_from_uint64(0)); -    if (ret) { -        dict_unref(local->xattr); -        free_inode_info(info); -        free_format(local); -        ret = ENOMEM; -        goto error; -    } -    local->fd = fd_ref(fd); - -    STACK_WIND(frame, crypt_create_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, -               xdata); -    return 0; -error: -    gf_log("crypt", GF_LOG_WARNING, "can not create file"); -    CRYPT_STACK_UNWIND(create, frame, -1, ret, NULL, NULL, NULL, NULL, NULL, -                       NULL); -    return 0; -} - -/* - * FIXME: this should depends on the version of format string - */ -static int32_t -filter_crypt_xattr(dict_t *dict, char *key, data_t *value, void *data) -{ -    dict_del(dict, key); -    return 0; -} - -static int32_t -crypt_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, -                int32_t flags, dict_t *xdata) -{ -    dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*", filter_crypt_xattr, -                         NULL); -    STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); -    return 0; -} - -/* - * TBD: verify file metadata before wind - */ -static int32_t -crypt_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, -               int32_t flags, dict_t *xdata) -{ -    dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*", filter_crypt_xattr, -                         NULL); -    STACK_WIND(frame, default_setxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); -    return 0; -} - -/* - * called as flush_cbk() - */ -static int32_t -linkop_end(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -           int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    linkop_unwind_handler_t unwind_fn; -    unwind_fn = linkop_unwind_dispatch(local->fop); - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0 && op_errno == ENOENT && -        local->loc->inode->ia_type == IA_IFLNK) { -        local->op_ret = 0; -        local->op_errno = 0; -    } -    unwind_fn(frame); -    return 0; -} - -/* - * unpin inode on the server - */ -static int32_t -link_flush(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -           int32_t op_errno, inode_t *inode, struct iatt *buf, -           struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        goto error; -    if (local->xdata) { -        dict_unref(local->xdata); -        local->xdata = NULL; -    } -    if (xdata) -        local->xdata = dict_ref(xdata); -    local->inode = inode_ref(inode); -    local->buf = *buf; -    local->prebuf = *preparent; -    local->postbuf = *postparent; - -    STACK_WIND(frame, linkop_end, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->flush, local->fd, NULL); -    return 0; -error: -    local->op_ret = -1; -    local->op_errno = op_errno; -    link_unwind(frame); -    return 0; -} - -void -link_unwind(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; -    dict_t *xdata; -    dict_t *xattr; -    inode_t *inode; - -    if (!local) { -        CRYPT_STACK_UNWIND(link, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, -                           NULL); -        return; -    } -    xdata = local->xdata; -    xattr = local->xattr; -    inode = local->inode; - -    if (local->loc) { -        loc_wipe(local->loc); -        GF_FREE(local->loc); -    } -    if (local->newloc) { -        loc_wipe(local->newloc); -        GF_FREE(local->newloc); -    } -    if (local->fd) -        fd_unref(local->fd); -    if (local->format) -        GF_FREE(local->format); - -    CRYPT_STACK_UNWIND(link, frame, local->op_ret, local->op_errno, inode, -                       &local->buf, &local->prebuf, &local->postbuf, xdata); -    if (xdata) -        dict_unref(xdata); -    if (xattr) -        dict_unref(xattr); -    if (inode) -        inode_unref(inode); -} - -void -link_wind(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; - -    STACK_WIND(frame, link_flush, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->link, local->loc, local->newloc, -               local->xdata); -} - -/* - * unlink() - */ -static int32_t -unlink_flush(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, struct iatt *preparent, struct iatt *postparent, -             dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        goto error; -    local->prebuf = *preparent; -    local->postbuf = *postparent; -    if (local->xdata) { -        dict_unref(local->xdata); -        local->xdata = NULL; -    } -    if (xdata) -        local->xdata = dict_ref(xdata); - -    STACK_WIND(frame, linkop_end, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->flush, local->fd, NULL); -    return 0; -error: -    local->op_ret = -1; -    local->op_errno = op_errno; -    unlink_unwind(frame); -    return 0; -} - -void -unlink_unwind(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; -    dict_t *xdata; -    dict_t *xattr; - -    if (!local) { -        CRYPT_STACK_UNWIND(unlink, frame, -1, ENOMEM, NULL, NULL, NULL); -        return; -    } -    xdata = local->xdata; -    xattr = local->xattr; -    if (local->loc) { -        loc_wipe(local->loc); -        GF_FREE(local->loc); -    } -    if (local->fd) -        fd_unref(local->fd); -    if (local->format) -        GF_FREE(local->format); - -    CRYPT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, -                       &local->prebuf, &local->postbuf, xdata); -    if (xdata) -        dict_unref(xdata); -    if (xattr) -        dict_unref(xattr); -} - -void -unlink_wind(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; - -    STACK_WIND(frame, unlink_flush, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->unlink, local->loc, local->flags, -               local->xdata); -} - -void -rename_unwind(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; -    dict_t *xdata; -    dict_t *xattr; -    struct iatt *prenewparent; -    struct iatt *postnewparent; - -    if (!local) { -        CRYPT_STACK_UNWIND(rename, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, -                           NULL, NULL); -        return; -    } -    xdata = local->xdata; -    xattr = local->xattr; -    prenewparent = local->prenewparent; -    postnewparent = local->postnewparent; - -    if (local->loc) { -        loc_wipe(local->loc); -        GF_FREE(local->loc); -    } -    if (local->newloc) { -        loc_wipe(local->newloc); -        GF_FREE(local->newloc); -    } -    if (local->fd) -        fd_unref(local->fd); -    if (local->format) -        GF_FREE(local->format); - -    CRYPT_STACK_UNWIND(rename, frame, local->op_ret, local->op_errno, -                       &local->buf, &local->prebuf, &local->postbuf, -                       prenewparent, postnewparent, xdata); -    if (xdata) -        dict_unref(xdata); -    if (xattr) -        dict_unref(xattr); -    if (prenewparent) -        GF_FREE(prenewparent); -    if (postnewparent) -        GF_FREE(postnewparent); -} - -/* - * called as flush_cbk() - */ -static int32_t -rename_end(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -           int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    rename_unwind(frame); -    return 0; -} - -static int32_t -rename_flush(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, -             struct iatt *postoldparent, struct iatt *prenewparent, -             struct iatt *postnewparent, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        goto error; -    dict_unref(local->xdata); -    local->xdata = NULL; -    if (xdata) -        local->xdata = dict_ref(xdata); - -    local->buf = *buf; -    local->prebuf = *preoldparent; -    local->postbuf = *postoldparent; -    if (prenewparent) { -        local->prenewparent = GF_CALLOC(1, sizeof(*prenewparent), -                                        gf_crypt_mt_iatt); -        if (!local->prenewparent) { -            op_errno = ENOMEM; -            goto error; -        } -        *local->prenewparent = *prenewparent; -    } -    if (postnewparent) { -        local->postnewparent = GF_CALLOC(1, sizeof(*postnewparent), -                                         gf_crypt_mt_iatt); -        if (!local->postnewparent) { -            op_errno = ENOMEM; -            goto error; -        } -        *local->postnewparent = *postnewparent; -    } -    STACK_WIND(frame, rename_end, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->flush, local->fd, NULL); -    return 0; -error: -    local->op_ret = -1; -    local->op_errno = op_errno; -    rename_unwind(frame); -    return 0; -} - -void -rename_wind(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; - -    STACK_WIND(frame, rename_flush, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->rename, local->loc, local->newloc, -               local->xdata); -} - -static int32_t -__do_linkop(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -            int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    linkop_wind_handler_t wind_fn; -    linkop_unwind_handler_t unwind_fn; - -    wind_fn = linkop_wind_dispatch(local->fop); -    unwind_fn = linkop_unwind_dispatch(local->fop); - -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret >= 0) -        wind_fn(frame, this); -    else { -        gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)", op_errno); -        unwind_fn(frame); -    } -    return 0; -} - -static int32_t -do_linkop(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -          int32_t op_errno, dict_t *xdata) -{ -    struct gf_flock lock = { -        0, -    }; -    crypt_local_t *local = frame->local; -    linkop_unwind_handler_t unwind_fn; - -    unwind_fn = linkop_unwind_dispatch(local->fop); -    local->op_ret = op_ret; -    local->op_errno = op_errno; - -    if (op_ret < 0) -        goto error; - -    lock.l_type = F_UNLCK; -    lock.l_whence = SEEK_SET; -    lock.l_start = 0; -    lock.l_len = 0; -    lock.l_pid = 0; - -    STACK_WIND(frame, __do_linkop, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, -               F_SETLKW, &lock, NULL); -    return 0; -error: -    unwind_fn(frame); -    return 0; -} - -/* - * Update the metadata string (against the new pathname); - * submit the result - */ -static int32_t -linkop_begin(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    gf_boolean_t upload_info; -    crypt_local_t *local = frame->local; -    crypt_private_t *priv = this->private; -    struct crypt_inode_info *info; -    data_t *old_mtd; -    uint32_t new_mtd_size; -    uint64_t value = 0; -    void (*unwind_fn)(call_frame_t * frame); -    mtd_op_t mop; - -    unwind_fn = linkop_unwind_dispatch(local->fop); -    mop = linkop_mtdop_dispatch(local->fop); - -    if (op_ret < 0) { -        /* -         * verification failed -         */ -        goto error; -    } else { -        fd_bind(fd); -    } - -    old_mtd = dict_get(xdata, CRYPTO_FORMAT_PREFIX); -    if (!old_mtd) { -        op_errno = EIO; -        gf_log(this->name, GF_LOG_DEBUG, "Metadata string wasn't found"); -        goto error; -    } -    new_mtd_size = format_size(mop, old_mtd->len); -    op_errno = alloc_format(local, new_mtd_size); -    if (op_errno) -        goto error; -    /* -     * check for cached info -     */ -    op_ret = inode_ctx_get(fd->inode, this, &value); -    if (op_ret != -1) { -        info = (struct crypt_inode_info *)(long)value; -        if (info == NULL) { -            gf_log(this->name, GF_LOG_WARNING, "Inode info was not found"); -            op_errno = EINVAL; -            goto error; -        } -        /* -         * info was found in the cache -         */ -        local->info = info; -        upload_info = _gf_false; -    } else { -        /* -         * info wasn't found in the cache; -         */ -        info = alloc_inode_info(local, local->loc); -        if (!info) -            goto error; -        init_inode_info_head(info, fd); -        local->info = info; -        upload_info = _gf_true; -    } -    op_errno = open_format((unsigned char *)old_mtd->data, old_mtd->len, -                           local->loc, info, get_master_cinfo(priv), local, -                           upload_info); -    if (op_errno) -        goto error; -    if (upload_info == _gf_true) { -        op_errno = init_inode_info_tail(info, get_master_cinfo(priv)); -        if (op_errno) -            goto error; -        op_errno = inode_ctx_put(fd->inode, this, (uint64_t)(long)(info)); -        if (op_errno == -1) { -            op_errno = EIO; -            goto error; -        } -    } -    /* -     * update the format string (append/update/cup a MAC) -     */ -    op_errno = update_format(local->format, (unsigned char *)old_mtd->data, -                             old_mtd->len, local->mac_idx, mop, local->newloc, -                             info, get_master_cinfo(priv), local); -    if (op_errno) -        goto error; -    /* -     * store the new format string on the server -     */ -    if (new_mtd_size) { -        op_errno = dict_set_static_bin(local->xattr, CRYPTO_FORMAT_PREFIX, -                                       local->format, new_mtd_size); -        if (op_errno) -            goto error; -    } -    STACK_WIND(frame, do_linkop, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->setxattr, local->loc, local->xattr, 0, -               NULL); -    return 0; -error: -    local->op_ret = -1; -    local->op_errno = op_errno; -    unwind_fn(frame); -    return 0; -} - -static int32_t -linkop_grab_local(call_frame_t *frame, xlator_t *this, loc_t *oldloc, -                  loc_t *newloc, int flags, dict_t *xdata, glusterfs_fop_t op) -{ -    int32_t ret = ENOMEM; -    fd_t *fd; -    crypt_local_t *local; - -    local = crypt_alloc_local(frame, this, op); -    if (!local) -        goto error; -    if (xdata) -        local->xdata = dict_ref(xdata); - -    fd = fd_create(oldloc->inode, frame->root->pid); -    if (!fd) { -        gf_log(this->name, GF_LOG_ERROR, "Can not create fd"); -        goto error; -    } -    local->fd = fd; -    local->flags = flags; -    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -    if (!local->loc) -        goto error; -    ret = loc_copy(local->loc, oldloc); -    if (ret) { -        GF_FREE(local->loc); -        local->loc = NULL; -        goto error; -    } -    if (newloc) { -        local->newloc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -        if (!local->newloc) { -            loc_wipe(local->loc); -            GF_FREE(local->loc); -            goto error; -        } -        ret = loc_copy(local->newloc, newloc); -        if (ret) { -            loc_wipe(local->loc); -            GF_FREE(local->loc); -            GF_FREE(local->newloc); -            goto error; -        } -    } -    local->xattr = dict_new(); -    if (!local->xattr) { -        gf_log(this->name, GF_LOG_ERROR, "Can not create dict"); -        ret = ENOMEM; -        goto error; -    } -    return 0; - -error: -    if (local) { -        if (local->xdata) -            dict_unref(local->xdata); -        if (local->fd) -            fd_unref(local->fd); -        local->fd = 0; -        local->loc = NULL; -        local->newloc = NULL; -        local->op_ret = -1; -        local->op_errno = ret; -    } - -    return ret; -} - -/* - * read and verify locked metadata against the old pathname (via open); - * update the metadata string in accordance with the new pathname; - * submit modified metadata; - * wind; - */ -static int32_t -linkop(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -       int flags, dict_t *xdata, glusterfs_fop_t op) -{ -    int32_t ret; -    dict_t *dict; -    crypt_local_t *local; -    void (*unwind_fn)(call_frame_t * frame); -    void (*wind_fn)(call_frame_t * frame, xlator_t * this); - -    wind_fn = linkop_wind_dispatch(op); -    unwind_fn = linkop_unwind_dispatch(op); - -    ret = linkop_grab_local(frame, this, oldloc, newloc, flags, xdata, op); -    local = frame->local; -    if (ret) -        goto error; - -    if (local->fd->inode->ia_type == IA_IFLNK) -        goto wind; - -    dict = dict_new(); -    if (!dict) { -        gf_log(this->name, GF_LOG_ERROR, "Can not create dict"); -        ret = ENOMEM; -        goto error; -    } -    /* -     * Set a message to crypt_open() that we need -     * locked metadata string. -     * All link operations (link, unlink, rename) -     * need write lock -     */ -    msgflags_set_mtd_wlock(&local->msgflags); -    ret = dict_set_static_bin(dict, MSGFLAGS_PREFIX, &local->msgflags, -                              sizeof(local->msgflags)); -    if (ret) { -        gf_log(this->name, GF_LOG_ERROR, "Can not set dict"); -        dict_unref(dict); -        goto error; -    } -    /* -     * verify metadata against the old pathname -     * and retrieve locked metadata string -     */ -    STACK_WIND(frame, linkop_begin, this, this->fops->open, /* crypt_open() */ -               oldloc, O_RDWR, local->fd, dict); -    dict_unref(dict); -    return 0; - -wind: -    wind_fn(frame, this); -    return 0; - -error: -    local->op_ret = -1; -    local->op_errno = ret; -    unwind_fn(frame); -    return 0; -} - -static int32_t -crypt_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -           dict_t *xdata) -{ -    return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_LINK); -} - -static int32_t -crypt_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, -             dict_t *xdata) -{ -    return linkop(frame, this, loc, NULL, flags, xdata, GF_FOP_UNLINK); -} - -static int32_t -crypt_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -             dict_t *xdata) -{ -    return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_RENAME); -} - -static void -put_one_call_open(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; -    if (put_one_call(local)) { -        fd_t *fd = local->fd; -        loc_t *loc = local->loc; -        dict_t *xdata = local->xdata; - -        CRYPT_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, fd, -                           xdata); -        fd_unref(fd); -        if (xdata) -            dict_unref(xdata); -        loc_wipe(loc); -        GF_FREE(loc); -    } -} - -static int32_t -__crypt_readv_done(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    fd_t *local_fd = local->fd; -    dict_t *local_xdata = local->xdata; -    /* read deals with data configs only */ -    struct iovec *avec = local->data_conf.avec; -    char **pool = local->data_conf.pool; -    int blocks_in_pool = local->data_conf.blocks_in_pool; -    struct iobref *iobref = local->iobref; -    struct iobref *iobref_data = local->iobref_data; - -    if (op_ret < 0) { -        gf_log(this->name, GF_LOG_WARNING, "readv unlock failed (%d)", -               op_errno); -        if (local->op_ret >= 0) { -            local->op_ret = op_ret; -            local->op_errno = op_errno; -        } -    } -    dump_plain_text(local, avec); - -    gf_log("crypt", GF_LOG_DEBUG, -           "readv: ret_to_user: %d, iovec len: %d, ia_size: %llu", -           (int)(local->rw_count > 0 ? local->rw_count : local->op_ret), -           (int)(local->rw_count > 0 ? iov_length(avec, local->data_conf.acount) -                                     : 0), -           (unsigned long long)local->buf.ia_size); - -    CRYPT_STACK_UNWIND( -        readv, frame, local->rw_count > 0 ? local->rw_count : local->op_ret, -        local->op_errno, avec, avec ? local->data_conf.acount : 0, &local->buf, -        local->iobref, local_xdata); - -    free_avec(avec, pool, blocks_in_pool); -    fd_unref(local_fd); -    if (local_xdata) -        dict_unref(local_xdata); -    if (iobref) -        iobref_unref(iobref); -    if (iobref_data) -        iobref_unref(iobref_data); -    return 0; -} - -static void -crypt_readv_done(call_frame_t *frame, xlator_t *this) -{ -    if (parent_is_crypt_xlator(frame, this)) -        /* -         *  don't unlock (it will be done by the parent) -         */ -        __crypt_readv_done(frame, NULL, this, 0, 0, NULL); -    else { -        crypt_local_t *local = frame->local; -        struct gf_flock lock = { -            0, -        }; - -        lock.l_type = F_UNLCK; -        lock.l_whence = SEEK_SET; -        lock.l_start = 0; -        lock.l_len = 0; -        lock.l_pid = 0; - -        STACK_WIND(frame, __crypt_readv_done, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, -                   F_SETLKW, &lock, NULL); -    } -} - -static void -put_one_call_readv(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; -    if (put_one_call(local)) -        crypt_readv_done(frame, this); -} - -static int32_t -__crypt_writev_done(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    fd_t *local_fd = local->fd; -    dict_t *local_xdata = local->xdata; -    int32_t ret_to_user; - -    if (local->xattr) -        dict_unref(local->xattr); -    /* -     * Calculate amount of butes to be returned -     * to user. We need to subtract paddings that -     * have been written as a part of atom. -     */ -    /* -     * subtract head padding -     */ -    if (local->rw_count == 0) -        /* -         * Nothing has been written, it must be an error -         */ -        ret_to_user = local->op_ret; -    else if (local->rw_count <= local->data_conf.off_in_head) { -        gf_log("crypt", GF_LOG_WARNING, "Incomplete write"); -        ret_to_user = 0; -    } else -        ret_to_user = local->rw_count - local->data_conf.off_in_head; -    /* -     * subtract tail padding -     */ -    if (ret_to_user > local->data_conf.orig_size) -        ret_to_user = local->data_conf.orig_size; - -    if (local->iobref) -        iobref_unref(local->iobref); -    if (local->iobref_data) -        iobref_unref(local->iobref_data); -    free_avec_data(local); -    free_avec_hole(local); - -    gf_log("crypt", GF_LOG_DEBUG, "writev: ret_to_user: %d", ret_to_user); - -    CRYPT_STACK_UNWIND(writev, frame, ret_to_user, local->op_errno, -                       &local->prebuf, &local->postbuf, local_xdata); -    fd_unref(local_fd); -    if (local_xdata) -        dict_unref(local_xdata); -    return 0; -} - -static int32_t -crypt_writev_done(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        gf_log("crypt", GF_LOG_WARNING, "can not update file size"); - -    if (parent_is_crypt_xlator(frame, this)) -        /* -         * don't unlock (it will be done by the parent) -         */ -        __crypt_writev_done(frame, NULL, this, 0, 0, NULL); -    else { -        struct gf_flock lock = { -            0, -        }; - -        lock.l_type = F_UNLCK; -        lock.l_whence = SEEK_SET; -        lock.l_start = 0; -        lock.l_len = 0; -        lock.l_pid = 0; - -        STACK_WIND(frame, __crypt_writev_done, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, -                   F_SETLKW, &lock, NULL); -    } -    return 0; -} - -static void -put_one_call_writev(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; -    if (put_one_call(local)) { -        if (local->update_disk_file_size) { -            int32_t ret; -            /* -             * update file size, unlock the file and unwind -             */ -            ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, -                           data_from_uint64(local->cur_file_size)); -            if (ret) { -                gf_log("crypt", GF_LOG_WARNING, -                       "can not set key to update file size"); -                crypt_writev_done(frame, NULL, this, 0, 0, NULL); -                return; -            } -            gf_log("crypt", GF_LOG_DEBUG, "Updating disk file size to %llu", -                   (unsigned long long)local->cur_file_size); -            STACK_WIND(frame, crypt_writev_done, FIRST_CHILD(this), -                       FIRST_CHILD(this)->fops->fsetxattr, local->fd, -                       local->xattr, /* CRYPTO_FORMAT_PREFIX */ -                       0, NULL); -        } else -            crypt_writev_done(frame, NULL, this, 0, 0, NULL); -    } -} - -static int32_t -__crypt_ftruncate_done(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    fd_t *local_fd = local->fd; -    dict_t *local_xdata = local->xdata; -    char *iobase = local->vec.iov_base; - -    if (op_ret < 0) { -        gf_log(this->name, GF_LOG_WARNING, "ftruncate unlock failed (%d)", -               op_errno); -        if (local->op_ret >= 0) { -            local->op_ret = op_ret; -            local->op_errno = op_errno; -        } -    } -    if (local->iobref_data) -        iobref_unref(local->iobref_data); -    free_avec_data(local); -    free_avec_hole(local); - -    gf_log("crypt", GF_LOG_DEBUG, -           "ftruncate, return to user: presize=%llu, postsize=%llu", -           (unsigned long long)local->prebuf.ia_size, -           (unsigned long long)local->postbuf.ia_size); - -    CRYPT_STACK_UNWIND(ftruncate, frame, ((local->op_ret < 0) ? -1 : 0), -                       local->op_errno, &local->prebuf, &local->postbuf, -                       local_xdata); -    fd_unref(local_fd); -    if (local_xdata) -        dict_unref(local_xdata); -    if (iobase) -        GF_FREE(iobase); -    return 0; -} - -static int32_t -crypt_ftruncate_done(call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    crypt_local_t *local = frame->local; -    struct gf_flock lock = { -        0, -    }; - -    dict_unref(local->xattr); -    if (op_ret < 0) -        gf_log("crypt", GF_LOG_WARNING, "can not update file size"); - -    lock.l_type = F_UNLCK; -    lock.l_whence = SEEK_SET; -    lock.l_start = 0; -    lock.l_len = 0; -    lock.l_pid = 0; - -    STACK_WIND(frame, __crypt_ftruncate_done, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, -               F_SETLKW, &lock, NULL); -    return 0; -} - -static void -put_one_call_ftruncate(call_frame_t *frame, xlator_t *this) -{ -    crypt_local_t *local = frame->local; -    if (put_one_call(local)) { -        if (local->update_disk_file_size) { -            int32_t ret; -            /* -             * update file size, unlock the file and unwind -             */ -            ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, -                           data_from_uint64(local->cur_file_size)); -            if (ret) { -                gf_log("crypt", GF_LOG_WARNING, -                       "can not set key to update file size"); -                crypt_ftruncate_done(frame, NULL, this, 0, 0, NULL); -                return; -            } -            gf_log("crypt", GF_LOG_DEBUG, "Updating disk file size to %llu", -                   (unsigned long long)local->cur_file_size); -            STACK_WIND(frame, crypt_ftruncate_done, FIRST_CHILD(this), -                       FIRST_CHILD(this)->fops->fsetxattr, local->fd, -                       local->xattr, /* CRYPTO_FORMAT_PREFIX */ -                       0, NULL); -        } else -            crypt_ftruncate_done(frame, NULL, this, 0, 0, NULL); -    } -} - -/* - * load regular file size for some FOPs - */ -static int32_t -load_file_size(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) -{ -    data_t *data; -    crypt_local_t *local = frame->local; - -    dict_t *local_xdata = local->xdata; -    inode_t *local_inode = local->inode; - -    if (op_ret < 0) -        goto unwind; -    /* -     * load regular file size -     */ -    data = dict_get(dict, FSIZE_XATTR_PREFIX); -    if (!data) { -        if (local->xdata) -            dict_unref(local->xdata); -        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -        op_ret = -1; -        op_errno = EIO; -        goto unwind; -    } -    local->buf.ia_size = data_to_uint64(data); - -    gf_log(this->name, GF_LOG_DEBUG, "FOP %d: Translate regular file to %llu", -           local->fop, (unsigned long long)local->buf.ia_size); -unwind: -    if (local->fd) -        fd_unref(local->fd); -    if (local->loc) { -        loc_wipe(local->loc); -        GF_FREE(local->loc); -    } -    switch (local->fop) { -        case GF_FOP_FSTAT: -            CRYPT_STACK_UNWIND(fstat, frame, op_ret, op_errno, -                               op_ret >= 0 ? &local->buf : NULL, local->xdata); -            break; -        case GF_FOP_STAT: -            CRYPT_STACK_UNWIND(stat, frame, op_ret, op_errno, -                               op_ret >= 0 ? &local->buf : NULL, local->xdata); -            break; -        case GF_FOP_LOOKUP: -            CRYPT_STACK_UNWIND(lookup, frame, op_ret, op_errno, -                               op_ret >= 0 ? local->inode : NULL, -                               op_ret >= 0 ? &local->buf : NULL, local->xdata, -                               op_ret >= 0 ? &local->postbuf : NULL); -            break; -        case GF_FOP_READ: -            CRYPT_STACK_UNWIND(readv, frame, op_ret, op_errno, NULL, 0, -                               op_ret >= 0 ? &local->buf : NULL, NULL, NULL); -            break; -        default: -            gf_log(this->name, GF_LOG_WARNING, "Improper file operation %d", -                   local->fop); -    } -    if (local_xdata) -        dict_unref(local_xdata); -    if (local_inode) -        inode_unref(local_inode); -    return 0; -} - -static int32_t -crypt_stat_common_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                      int32_t op_ret, int32_t op_errno, struct iatt *buf, -                      dict_t *xdata) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        goto unwind; -    if (!IA_ISREG(buf->ia_type)) -        goto unwind; - -    local->buf = *buf; -    if (xdata) -        local->xdata = dict_ref(xdata); - -    switch (local->fop) { -        case GF_FOP_FSTAT: -            STACK_WIND(frame, load_file_size, FIRST_CHILD(this), -                       FIRST_CHILD(this)->fops->fgetxattr, local->fd, -                       FSIZE_XATTR_PREFIX, NULL); -            break; -        case GF_FOP_STAT: -            STACK_WIND(frame, load_file_size, FIRST_CHILD(this), -                       FIRST_CHILD(this)->fops->getxattr, local->loc, -                       FSIZE_XATTR_PREFIX, NULL); -            break; -        default: -            gf_log(this->name, GF_LOG_WARNING, "Improper file operation %d", -                   local->fop); -    } -    return 0; -unwind: -    if (local->fd) -        fd_unref(local->fd); -    if (local->loc) { -        loc_wipe(local->loc); -        GF_FREE(local->loc); -    } -    switch (local->fop) { -        case GF_FOP_FSTAT: -            CRYPT_STACK_UNWIND(fstat, frame, op_ret, op_errno, -                               op_ret >= 0 ? buf : NULL, -                               op_ret >= 0 ? xdata : NULL); -            break; -        case GF_FOP_STAT: -            CRYPT_STACK_UNWIND(stat, frame, op_ret, op_errno, -                               op_ret >= 0 ? buf : NULL, -                               op_ret >= 0 ? xdata : NULL); -            break; -        default: -            gf_log(this->name, GF_LOG_WARNING, "Improper file operation %d", -                   local->fop); -    } -    return 0; -} - -static int32_t -crypt_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) -{ -    crypt_local_t *local; - -    local = crypt_alloc_local(frame, this, GF_FOP_FSTAT); -    if (!local) -        goto error; -    local->fd = fd_ref(fd); -    STACK_WIND(frame, crypt_stat_common_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fstat, fd, xdata); -    return 0; -error: -    CRYPT_STACK_UNWIND(fstat, frame, -1, ENOMEM, NULL, NULL); -    return 0; -} - -static int32_t -crypt_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    int32_t ret; -    crypt_local_t *local; - -    local = crypt_alloc_local(frame, this, GF_FOP_STAT); -    if (!local) -        goto error; -    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -    if (!local->loc) -        goto error; -    ret = loc_copy(local->loc, loc); -    if (ret) { -        GF_FREE(local->loc); -        goto error; -    } -    STACK_WIND(frame, crypt_stat_common_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->stat, loc, xdata); -    return 0; -error: -    CRYPT_STACK_UNWIND(stat, frame, -1, ENOMEM, NULL, NULL); -    return 0; -} - -static int32_t -crypt_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, inode_t *inode, -                 struct iatt *buf, dict_t *xdata, struct iatt *postparent) -{ -    crypt_local_t *local = frame->local; - -    if (op_ret < 0) -        goto unwind; -    if (!IA_ISREG(buf->ia_type)) -        goto unwind; - -    local->inode = inode_ref(inode); -    local->buf = *buf; -    local->postbuf = *postparent; -    if (xdata) -        local->xdata = dict_ref(xdata); -    gf_uuid_copy(local->loc->gfid, buf->ia_gfid); - -    STACK_WIND(frame, load_file_size, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->getxattr, local->loc, -               FSIZE_XATTR_PREFIX, NULL); -    return 0; -unwind: -    loc_wipe(local->loc); -    GF_FREE(local->loc); -    CRYPT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, xdata, -                       postparent); -    return 0; -} - -static int32_t -crypt_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    int32_t ret; -    crypt_local_t *local; - -    local = crypt_alloc_local(frame, this, GF_FOP_LOOKUP); -    if (!local) -        goto error; -    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -    if (!local->loc) -        goto error; -    ret = loc_copy(local->loc, loc); -    if (ret) { -        GF_FREE(local->loc); -        goto error; -    } -    gf_log(this->name, GF_LOG_DEBUG, "Lookup %s", loc->path); -    STACK_WIND(frame, crypt_lookup_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lookup, loc, xdata); -    return 0; -error: -    CRYPT_STACK_UNWIND(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); -    return 0; -} - -/* - * for every regular directory entry find its real file size - * and update stat's buf properly - */ -static int32_t -crypt_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, -                   dict_t *xdata) -{ -    gf_dirent_t *entry = NULL; - -    if (op_ret < 0) -        goto unwind; - -    list_for_each_entry(entry, (&entries->list), list) -    { -        data_t *data; - -        if (!IA_ISREG(entry->d_stat.ia_type)) -            continue; -        data = dict_get(entry->dict, FSIZE_XATTR_PREFIX); -        if (!data) { -            gf_log("crypt", GF_LOG_WARNING, -                   "Regular file size of direntry not found"); -            op_errno = EIO; -            op_ret = -1; -            break; -        } -        entry->d_stat.ia_size = data_to_uint64(data); -    } -unwind: -    CRYPT_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); -    return 0; -} - -/* - * ->readdirp() fills in-core inodes, so we need to set proper - * file sizes for all directory entries of the parent @fd. - * Actual updates take place in ->crypt_readdirp_cbk() - */ -static int32_t -crypt_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -               off_t offset, dict_t *xdata) -{ -    int32_t ret = ENOMEM; - -    if (!xdata) { -        xdata = dict_new(); -        if (!xdata) -            goto error; -    } else -        dict_ref(xdata); -    /* -     * make sure that we'll have real file sizes at ->readdirp_cbk() -     */ -    ret = dict_set(xdata, FSIZE_XATTR_PREFIX, data_from_uint64(0)); -    if (ret) { -        dict_unref(xdata); -        ret = ENOMEM; -        goto error; -    } -    STACK_WIND(frame, crypt_readdirp_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readdirp, fd, size, offset, xdata); -    dict_unref(xdata); -    return 0; -error: -    CRYPT_STACK_UNWIND(readdirp, frame, -1, ret, NULL, NULL); -    return 0; -} - -static int32_t -crypt_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, -             dict_t *xdata) -{ -    gf_log(this->name, GF_LOG_WARNING, -           "NFS mounts of encrypted volumes are unsupported"); -    CRYPT_STACK_UNWIND(access, frame, -1, EPERM, NULL); -    return 0; -} - -int32_t -master_set_block_size(xlator_t *this, crypt_private_t *priv, dict_t *options) -{ -    uint64_t block_size = 0; -    struct master_cipher_info *master = get_master_cinfo(priv); - -    if (options != NULL) -        GF_OPTION_RECONF("block-size", block_size, options, size_uint64, error); -    else -        GF_OPTION_INIT("block-size", block_size, size_uint64, error); - -    switch (block_size) { -        case 512: -            master->m_block_bits = 9; -            break; -        case 1024: -            master->m_block_bits = 10; -            break; -        case 2048: -            master->m_block_bits = 11; -            break; -        case 4096: -            master->m_block_bits = 12; -            break; -        default: -            gf_log("crypt", GF_LOG_ERROR, "FATAL: unsupported block size %llu", -                   (unsigned long long)block_size); -            goto error; -    } -    return 0; -error: -    return -1; -} - -int32_t -master_set_alg(xlator_t *this, crypt_private_t *priv) -{ -    struct master_cipher_info *master = get_master_cinfo(priv); -    master->m_alg = AES_CIPHER_ALG; -    return 0; -} - -int32_t -master_set_mode(xlator_t *this, crypt_private_t *priv) -{ -    struct master_cipher_info *master = get_master_cinfo(priv); -    master->m_mode = XTS_CIPHER_MODE; -    return 0; -} - -/* - * set key size in bits to the master info - * Pre-conditions: cipher mode in the master info is uptodate. - */ -static int -master_set_data_key_size(xlator_t *this, crypt_private_t *priv, dict_t *options) -{ -    int32_t ret; -    uint64_t key_size = 0; -    struct master_cipher_info *master = get_master_cinfo(priv); - -    if (options != NULL) -        GF_OPTION_RECONF("data-key-size", key_size, options, uint64, error); -    else -        GF_OPTION_INIT("data-key-size", key_size, uint64, error); - -    ret = data_cipher_algs[master->m_alg][master->m_mode].check_key(key_size); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, -               "FATAL: wrong bin key size %llu for alg %d mode %d", -               (unsigned long long)key_size, (int)master->m_alg, -               (int)master->m_mode); -        goto error; -    } -    master->m_dkey_size = key_size; -    return 0; -error: -    return -1; -} - -static int -is_hex(char *s) -{ -    return ('0' <= *s && *s <= '9') || ('a' <= *s && *s <= 'f'); -} - -static int -parse_hex_buf(xlator_t *this, char *src, unsigned char *dst, int hex_size) -{ -    int i; -    int hex_byte = 0; - -    for (i = 0; i < (hex_size / 2); i++) { -        if (!is_hex(src + i * 2) || !is_hex(src + i * 2 + 1)) { -            gf_log("crypt", GF_LOG_ERROR, "FATAL: not hex symbol in key"); -            return -1; -        } -        if (sscanf(src + i * 2, "%2x", &hex_byte) != 1) { -            gf_log("crypt", GF_LOG_ERROR, "FATAL: can not parse hex key"); -            return -1; -        } -        dst[i] = hex_byte & 0xff; -    } -    return 0; -} - -/* - * Parse options; - * install master volume key - */ -int32_t -master_set_master_vol_key(xlator_t *this, crypt_private_t *priv) -{ -    int32_t ret; -    FILE *file = NULL; - -    int32_t key_size; -    char *opt_key_file_pathname = NULL; - -    unsigned char bin_buf[MASTER_VOL_KEY_SIZE]; -    char hex_buf[2 * MASTER_VOL_KEY_SIZE]; - -    struct master_cipher_info *master = get_master_cinfo(priv); -    /* -     * extract master key passed via option -     */ -    GF_OPTION_INIT("master-key", opt_key_file_pathname, path, bad_key); - -    if (!opt_key_file_pathname) { -        gf_log(this->name, GF_LOG_ERROR, "FATAL: missing master key"); -        return -1; -    } -    gf_log(this->name, GF_LOG_DEBUG, "handling file key %s", -           opt_key_file_pathname); - -    file = fopen(opt_key_file_pathname, "r"); -    if (file == NULL) { -        gf_log(this->name, GF_LOG_ERROR, -               "FATAL: can not open file with master key"); -        return -1; -    } -    /* -     * extract hex key -     */ -    key_size = fread(hex_buf, 1, sizeof(hex_buf), file); -    if (key_size < sizeof(hex_buf)) { -        gf_log(this->name, GF_LOG_ERROR, "FATAL: master key is too short"); -        goto bad_key; -    } -    ret = parse_hex_buf(this, hex_buf, bin_buf, key_size); -    if (ret) -        goto bad_key; -    memcpy(master->m_key, bin_buf, MASTER_VOL_KEY_SIZE); -    memset(hex_buf, 0, sizeof(hex_buf)); -    fclose(file); - -    memset(bin_buf, 0, sizeof(bin_buf)); -    return 0; -bad_key: -    gf_log(this->name, GF_LOG_ERROR, "FATAL: bad master key"); -    if (file) -        fclose(file); -    memset(bin_buf, 0, sizeof(bin_buf)); -    return -1; -} - -/* - * Derive volume key for object-id authentication - */ -int32_t -master_set_nmtd_vol_key(xlator_t *this, crypt_private_t *priv) -{ -    return get_nmtd_vol_key(get_master_cinfo(priv)); -} - -int32_t -crypt_init_xlator(xlator_t *this) -{ -    int32_t ret; -    crypt_private_t *priv = this->private; - -    ret = master_set_alg(this, priv); -    if (ret) -        return ret; -    ret = master_set_mode(this, priv); -    if (ret) -        return ret; -    ret = master_set_block_size(this, priv, NULL); -    if (ret) -        return ret; -    ret = master_set_data_key_size(this, priv, NULL); -    if (ret) -        return ret; -    ret = master_set_master_vol_key(this, priv); -    if (ret) -        return ret; -    return master_set_nmtd_vol_key(this, priv); -} - -static int32_t -crypt_alloc_private(xlator_t *this) -{ -    this->private = GF_CALLOC(1, sizeof(crypt_private_t), gf_crypt_mt_priv); -    if (!this->private) { -        gf_log("crypt", GF_LOG_ERROR, -               "Can not allocate memory for private data"); -        return ENOMEM; -    } -    return 0; -} - -static void -crypt_free_private(xlator_t *this) -{ -    crypt_private_t *priv = this->private; -    if (priv) { -        memset(priv, 0, sizeof(*priv)); -        GF_FREE(priv); -    } -} - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    if (!this) -        return ret; - -    ret = xlator_mem_acct_init(this, gf_crypt_mt_end); - -    if (ret != 0) { -        gf_log(this->name, GF_LOG_ERROR, -               "Memory accounting init" -               "failed"); -        return ret; -    } - -    return ret; -} - -int32_t -reconfigure(xlator_t *this, dict_t *options) -{ -    int32_t ret = -1; -    crypt_private_t *priv = NULL; - -    GF_VALIDATE_OR_GOTO("crypt", this, error); -    GF_VALIDATE_OR_GOTO(this->name, this->private, error); -    GF_VALIDATE_OR_GOTO(this->name, options, error); - -    priv = this->private; - -    ret = master_set_block_size(this, priv, options); -    if (ret) { -        gf_log("this->name", GF_LOG_ERROR, "Failed to reconfure block size"); -        goto error; -    } -    ret = master_set_data_key_size(this, priv, options); -    if (ret) { -        gf_log("this->name", GF_LOG_ERROR, "Failed to reconfure data key size"); -        goto error; -    } -    return 0; -error: -    return ret; -} - -int32_t -init(xlator_t *this) -{ -    int32_t ret; - -    if (!this->children || this->children->next) { -        gf_log("crypt", GF_LOG_ERROR, -               "FATAL: crypt should have exactly one child"); -        return EINVAL; -    } -    if (!this->parents) { -        gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); -    } -    ret = crypt_alloc_private(this); -    if (ret) -        return ret; -    ret = crypt_init_xlator(this); -    if (ret) -        goto error; -    this->local_pool = mem_pool_new(crypt_local_t, 64); -    if (!this->local_pool) { -        gf_log(this->name, GF_LOG_ERROR, -               "failed to create local_t's memory pool"); -        ret = ENOMEM; -        goto error; -    } -    gf_log("crypt", GF_LOG_INFO, "crypt xlator loaded"); -    return 0; -error: -    crypt_free_private(this); -    return ret; -} - -void -fini(xlator_t *this) -{ -    crypt_free_private(this); -} - -struct xlator_fops fops = {.readv = crypt_readv, -                           .writev = crypt_writev, -                           .truncate = crypt_truncate, -                           .ftruncate = crypt_ftruncate, -                           .setxattr = crypt_setxattr, -                           .fsetxattr = crypt_fsetxattr, -                           .link = crypt_link, -                           .unlink = crypt_unlink, -                           .rename = crypt_rename, -                           .open = crypt_open, -                           .create = crypt_create, -                           .stat = crypt_stat, -                           .fstat = crypt_fstat, -                           .lookup = crypt_lookup, -                           .readdirp = crypt_readdirp, -                           .access = crypt_access}; - -struct xlator_cbks cbks = {.forget = crypt_forget}; - -struct volume_options options[] = { -    {.key = {"master-key"}, -     .type = GF_OPTION_TYPE_PATH, -     .description = -         "Pathname of regular file which contains master volume key"}, -    { -        .key = {"data-key-size"}, -        .type = GF_OPTION_TYPE_SIZET, -        .description = "Data key size (bits)", -        .min = 256, -        .max = 512, -        .default_value = "256", -    }, -    {.key = {"block-size"}, -     .type = GF_OPTION_TYPE_SIZET, -     .description = "Atom size (bits)", -     .min = 512, -     .max = 4096, -     .default_value = "4096"}, -    {.key = {NULL}}, -}; - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/crypt.h b/xlators/encryption/crypt/src/crypt.h deleted file mode 100644 index c1216a2cdb0..00000000000 --- a/xlators/encryption/crypt/src/crypt.h +++ /dev/null @@ -1,931 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __CRYPT_H__ -#define __CRYPT_H__ - -#include <openssl/aes.h> -#include <openssl/evp.h> -#include <openssl/sha.h> -#include <openssl/hmac.h> -#include <openssl/cmac.h> -#include <openssl/modes.h> -#include "crypt-mem-types.h" -#include <glusterfs/compat.h> - -#define CRYPT_XLATOR_ID (0) - -#define MAX_IOVEC_BITS (3) -#define MAX_IOVEC (1 << MAX_IOVEC_BITS) -#define KEY_FACTOR_BITS (6) - -#define DEBUG_CRYPT (0) -#define TRIVIAL_TFM (0) - -#define CRYPT_MIN_BLOCK_BITS (9) -#define CRYPT_MAX_BLOCK_BITS (12) - -#define MASTER_VOL_KEY_SIZE (32) -#define NMTD_VOL_KEY_SIZE (16) - -#if !defined(GF_LINUX_HOST_OS) -typedef off_t loff_t; -#endif - -struct crypt_key { -    uint32_t len; -    const char *label; -}; - -/* - * Add new key types to the end of this - * enumeration but before LAST_KEY_TYPE - */ -typedef enum { -    MASTER_VOL_KEY, -    NMTD_VOL_KEY, -    NMTD_LINK_KEY, -    EMTD_FILE_KEY, -    DATA_FILE_KEY_256, -    DATA_FILE_KEY_512, -    LAST_KEY_TYPE -} crypt_key_type; - -struct kderive_context { -    const unsigned char *pkey; /* parent key */ -    uint32_t pkey_len;         /* parent key size, bits */ -    uint32_t ckey_len;         /* child key size, bits */ -    unsigned char *fid;        /* fixed input data, NIST 800-108, 5.1 */ -    uint32_t fid_len;          /* fid len, bytes */ -    unsigned char *out;        /* contains child keying material */ -    uint32_t out_len;          /* out len, bytes */ -}; - -typedef enum { DATA_ATOM, HOLE_ATOM, LAST_DATA_TYPE } atom_data_type; - -typedef enum { -    HEAD_ATOM, -    TAIL_ATOM, -    FULL_ATOM, -    LAST_LOCALITY_TYPE -} atom_locality_type; - -typedef enum { -    MTD_CREATE, -    MTD_APPEND, -    MTD_OVERWRITE, -    MTD_CUT, -    MTD_LAST_OP -} mtd_op_t; - -struct xts128_context { -    void *key1, *key2; -    block128_f block1, block2; -}; - -struct object_cipher_info { -    cipher_alg_t o_alg; -    cipher_mode_t o_mode; -    uint32_t o_block_bits; -    uint32_t o_dkey_size; /* raw data key size in bits */ -    union { -        struct { -            unsigned char ivec[16]; -            AES_KEY dkey[2]; -            AES_KEY tkey; /* key used for tweaking */ -            XTS128_CONTEXT xts; -        } aes_xts; -    } u; -}; - -struct master_cipher_info { -    /* -     * attributes inherited by newly created regular files -     */ -    cipher_alg_t m_alg; -    cipher_mode_t m_mode; -    uint32_t m_block_bits; -    uint32_t m_dkey_size; /* raw key size in bits */ -    /* -     * master key -     */ -    unsigned char m_key[MASTER_VOL_KEY_SIZE]; -    /* -     * volume key for oid authentication -     */ -    unsigned char m_nmtd_key[NMTD_VOL_KEY_SIZE]; -}; - -/* - * This info is not changed during file's life - */ -struct crypt_inode_info { -#if DEBUG_CRYPT -    loc_t *loc; /* pathname that the file has been -                   opened, or created with */ -#endif -    uint16_t nr_minor; -    uuid_t oid; -    struct object_cipher_info cinfo; -}; - -/* - * this should locate in secure memory - */ -typedef struct { -    struct master_cipher_info master; -} crypt_private_t; - -static inline struct master_cipher_info * -get_master_cinfo(crypt_private_t *priv) -{ -    return &priv->master; -} - -static inline struct object_cipher_info * -get_object_cinfo(struct crypt_inode_info *info) -{ -    return &info->cinfo; -} - -/* - * this describes layouts and properties - * of atoms in an aligned vector - */ -struct avec_config { -    uint32_t atom_size; -    atom_data_type type; -    size_t orig_size; -    off_t orig_offset; -    size_t expanded_size; -    off_t aligned_offset; - -    uint32_t off_in_head; -    uint32_t off_in_tail; -    uint32_t gap_in_tail; -    uint32_t nr_full_blocks; - -    struct iovec *avec; /* aligned vector */ -    uint32_t acount;    /* number of avec components. The same -                         * as number of occupied logical blocks */ -    char **pool; -    uint32_t blocks_in_pool; -    uint32_t cursor; /* makes sense only for ordered writes, -                      * so there is no races on this counter. -                      * -                      * Cursor is per-config object, we don't -                      * reset cursor for atoms of different -                      * localities (head, tail, full) -                      */ -}; - -typedef struct { -    glusterfs_fop_t fop; /* code of FOP this local info built for */ -    fd_t *fd; -    inode_t *inode; -    loc_t *loc; -    int32_t mac_idx; -    loc_t *newloc; -    int32_t flags; -    int32_t wbflags; -    struct crypt_inode_info *info; -    struct iobref *iobref; -    struct iobref *iobref_data; -    off_t offset; - -    uint64_t old_file_size; /* per FOP, retrieved under lock held */ -    uint64_t cur_file_size; /* per iteration, before issuing IOs */ -    uint64_t new_file_size; /* per iteration, after issuing IOs */ - -    uint64_t io_offset;        /* offset of IOs issued per iteration */ -    uint64_t io_offset_nopad;  /* offset of user's data in the atom */ -    uint32_t io_size;          /* size of IOs issued per iteration */ -    uint32_t io_size_nopad;    /* size of user's data in the IOs */ -    uint32_t eof_padding_size; /* size od EOF padding in the IOs */ - -    gf_lock_t call_lock; /* protect nr_calls from many cbks */ -    int32_t nr_calls; - -    atom_data_type active_setup; /* which setup (hole or date) -                                    is currently active */ -    /* data setup */ -    struct avec_config data_conf; - -    /* hole setup */ -    int hole_conv_in_proggress; -    gf_lock_t hole_lock; /* protect hole config from many cbks */ -    int hole_handled; -    struct avec_config hole_conf; -    struct iatt buf; -    struct iatt prebuf; -    struct iatt postbuf; -    struct iatt *prenewparent; -    struct iatt *postnewparent; -    int32_t op_ret; -    int32_t op_errno; -    int32_t rw_count;        /* total read or written */ -    gf_lock_t rw_count_lock; /* protect the counter above */ -    unsigned char *format;   /* for create, update format string */ -    uint32_t format_size; -    uint32_t msgflags; /* messages for crypt_open() */ -    dict_t *xdata; -    dict_t *xattr; -    struct iovec vec; /* contains last file's atom for -                         read-prune-write sequence */ -    gf_boolean_t custom_mtd; -    /* -     * the next 3 fields are used by readdir and friends -     */ -    gf_dirent_t *de;        /* directory entry */ -    char *de_path;          /* pathname of directory entry */ -    uint32_t de_prefix_len; /* length of the parent's pathname */ -    gf_dirent_t *entries; - -    uint32_t update_disk_file_size : 1; -} crypt_local_t; - -/* This represents a (read)modify-write atom */ -struct rmw_atom { -    atom_locality_type locality; -    /* -     * read-modify-write sequence of the atom -     */ -    int32_t (*rmw)(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, struct iovec *vec, -                   int32_t count, struct iatt *stbuf, struct iobref *iobref, -                   dict_t *xdata); -    /* -     * offset of the logical block in a file -     */ -    loff_t (*offset_at)(call_frame_t *frame, struct object_cipher_info *object); -    /* -     * IO offset in an atom -     */ -    uint32_t (*offset_in)(call_frame_t *frame, -                          struct object_cipher_info *object); -    /* -     * number of bytes of plain text of this atom that user -     * wants to read/write. -     * It can be smaller than atom_size in the case of head -     * or tail atoms. -     */ -    uint32_t (*io_size_nopad)(call_frame_t *frame, -                              struct object_cipher_info *object); -    /* -     * which iovec represents the atom -     */ -    struct iovec *(*get_iovec)(call_frame_t *frame, uint32_t count); -    /* -     * how many bytes of partial block should be uptodated by -     * reading from disk. -     * This is used to perform a read component of RMW (read-modify-write). -     */ -    uint32_t (*count_to_uptodate)(call_frame_t *frame, -                                  struct object_cipher_info *object); -    struct avec_config *(*get_config)(call_frame_t *frame); -}; - -struct data_cipher_alg { -    gf_boolean_t atomic;     /* true means that algorithm requires -                                to pad data before cipher transform */ -    gf_boolean_t should_pad; /* true means that algorithm requires -                                to pad the end of file with extra-data */ -    uint32_t blkbits;        /* blksize = 1 << blkbits */ -    /* -     * any preliminary sanity checks goes here -     */ -    int32_t (*init)(void); -    /* -     * set alg-mode specific inode info -     */ -    int32_t (*set_private)(struct crypt_inode_info *info, -                           struct master_cipher_info *master); -    /* -     * check alg-mode specific data key -     */ -    int32_t (*check_key)(uint32_t key_size); -    void (*set_iv)(off_t offset, struct object_cipher_info *object); -    int32_t (*encrypt)(const unsigned char *from, unsigned char *to, -                       size_t length, off_t offset, const int enc, -                       struct object_cipher_info *object); -}; - -/* - * version-dependent metadata loader - */ -struct crypt_mtd_loader { -    /* -     * return core format size -     */ -    size_t (*format_size)(mtd_op_t op, size_t old_size); -    /* -     * pack version-specific metadata of an object -     * at ->create() -     */ -    int32_t (*create_format)(unsigned char *wire, loc_t *loc, -                             struct crypt_inode_info *info, -                             struct master_cipher_info *master); -    /* -     * extract version-specific metadata of an object -     * at ->open() time -     */ -    int32_t (*open_format)(unsigned char *wire, int32_t len, loc_t *loc, -                           struct crypt_inode_info *info, -                           struct master_cipher_info *master, -                           crypt_local_t *local, gf_boolean_t load_info); -    int32_t (*update_format)(unsigned char *new, unsigned char *old, -                             size_t old_len, int32_t mac_idx, mtd_op_t op, -                             loc_t *loc, struct crypt_inode_info *info, -                             struct master_cipher_info *master, -                             crypt_local_t *local); -}; - -typedef int32_t (*end_writeback_handler_t)(call_frame_t *frame, void *cookie, -                                           xlator_t *this, int32_t op_ret, -                                           int32_t op_errno, -                                           struct iatt *prebuf, -                                           struct iatt *postbuf, dict_t *xdata); -typedef void (*linkop_wind_handler_t)(call_frame_t *frame, xlator_t *this); -typedef void (*linkop_unwind_handler_t)(call_frame_t *frame); - -/* Declarations */ - -/* keys.c */ -extern struct crypt_key crypt_keys[LAST_KEY_TYPE]; -int32_t -get_nmtd_vol_key(struct master_cipher_info *master); -int32_t -get_nmtd_link_key(loc_t *loc, struct master_cipher_info *master, -                  unsigned char *result); -int32_t -get_emtd_file_key(struct crypt_inode_info *info, -                  struct master_cipher_info *master, unsigned char *result); -int32_t -get_data_file_key(struct crypt_inode_info *info, -                  struct master_cipher_info *master, uint32_t keysize, -                  unsigned char *key); -/* data.c */ -extern struct data_cipher_alg data_cipher_algs[LAST_CIPHER_ALG] -                                              [LAST_CIPHER_MODE]; -void -encrypt_aligned_iov(struct object_cipher_info *object, struct iovec *vec, -                    int count, off_t off); -void -decrypt_aligned_iov(struct object_cipher_info *object, struct iovec *vec, -                    int count, off_t off); -int32_t -align_iov_by_atoms(xlator_t *this, crypt_local_t *local, -                   struct object_cipher_info *object, -                   struct iovec *vec /* input vector */, -                   int32_t count /* number of vec components */, -                   struct iovec *avec /* aligned vector */, -                   char **blocks /* pool of blocks */, -                   uint32_t *blocks_allocated, struct avec_config *conf); -int32_t -set_config_avec_data(xlator_t *this, crypt_local_t *local, -                     struct avec_config *conf, -                     struct object_cipher_info *object, struct iovec *vec, -                     int32_t vec_count); -int32_t -set_config_avec_hole(xlator_t *this, crypt_local_t *local, -                     struct avec_config *conf, -                     struct object_cipher_info *object, glusterfs_fop_t fop); -void -set_gap_at_end(call_frame_t *frame, struct object_cipher_info *object, -               struct avec_config *conf, atom_data_type dtype); -void -set_config_offsets(call_frame_t *frame, xlator_t *this, uint64_t offset, -                   uint64_t count, atom_data_type dtype, -                   int32_t setup_gap_in_tail); - -/* metadata.c */ -extern struct crypt_mtd_loader mtd_loaders[LAST_MTD_LOADER]; - -int32_t -alloc_format(crypt_local_t *local, size_t size); -int32_t -alloc_format_create(crypt_local_t *local); -void -free_format(crypt_local_t *local); -size_t -format_size(mtd_op_t op, size_t old_size); -size_t -new_format_size(void); -int32_t -open_format(unsigned char *str, int32_t len, loc_t *loc, -            struct crypt_inode_info *info, struct master_cipher_info *master, -            crypt_local_t *local, gf_boolean_t load_info); -int32_t -update_format(unsigned char *new, unsigned char *old, size_t old_len, -              int32_t mac_idx, mtd_op_t op, loc_t *loc, -              struct crypt_inode_info *info, struct master_cipher_info *master, -              crypt_local_t *local); -int32_t -create_format(unsigned char *wire, loc_t *loc, struct crypt_inode_info *info, -              struct master_cipher_info *master); - -/* atom.c */ -struct rmw_atom * -atom_by_types(atom_data_type data, atom_locality_type locality); -void -submit_partial(call_frame_t *frame, xlator_t *this, fd_t *fd, -               atom_locality_type ltype); -void -submit_full(call_frame_t *frame, xlator_t *this); - -/* crypt.c */ - -end_writeback_handler_t -dispatch_end_writeback(glusterfs_fop_t fop); -void -set_local_io_params_writev(call_frame_t *frame, -                           struct object_cipher_info *object, -                           struct rmw_atom *atom, off_t io_offset, -                           uint32_t io_size); -void -link_wind(call_frame_t *frame, xlator_t *this); -void -unlink_wind(call_frame_t *frame, xlator_t *this); -void -link_unwind(call_frame_t *frame); -void -unlink_unwind(call_frame_t *frame); -void -rename_wind(call_frame_t *frame, xlator_t *this); -void -rename_unwind(call_frame_t *frame); - -/* Inline functions */ - -static inline int32_t -crypt_xlator_id(void) -{ -    return CRYPT_XLATOR_ID; -} - -static inline mtd_loader_id -current_mtd_loader(void) -{ -    return MTD_LOADER_V1; -} - -static inline uint32_t -master_key_size(void) -{ -    return crypt_keys[MASTER_VOL_KEY].len >> 3; -} - -static inline uint32_t -nmtd_vol_key_size(void) -{ -    return crypt_keys[NMTD_VOL_KEY].len >> 3; -} - -static inline uint32_t -alg_mode_blkbits(cipher_alg_t alg, cipher_mode_t mode) -{ -    return data_cipher_algs[alg][mode].blkbits; -} - -static inline uint32_t -alg_mode_blksize(cipher_alg_t alg, cipher_mode_t mode) -{ -    return 1 << alg_mode_blkbits(alg, mode); -} - -static inline gf_boolean_t -alg_mode_atomic(cipher_alg_t alg, cipher_mode_t mode) -{ -    return data_cipher_algs[alg][mode].atomic; -} - -static inline gf_boolean_t -alg_mode_should_pad(cipher_alg_t alg, cipher_mode_t mode) -{ -    return data_cipher_algs[alg][mode].should_pad; -} - -static inline uint32_t -master_alg_blksize(struct master_cipher_info *mr) -{ -    return alg_mode_blksize(mr->m_alg, mr->m_mode); -} - -static inline uint32_t -master_alg_blkbits(struct master_cipher_info *mr) -{ -    return alg_mode_blkbits(mr->m_alg, mr->m_mode); -} - -static inline gf_boolean_t -master_alg_atomic(struct master_cipher_info *mr) -{ -    return alg_mode_atomic(mr->m_alg, mr->m_mode); -} - -static inline gf_boolean_t -master_alg_should_pad(struct master_cipher_info *mr) -{ -    return alg_mode_should_pad(mr->m_alg, mr->m_mode); -} - -static inline uint32_t -object_alg_blksize(struct object_cipher_info *ob) -{ -    return alg_mode_blksize(ob->o_alg, ob->o_mode); -} - -static inline uint32_t -object_alg_blkbits(struct object_cipher_info *ob) -{ -    return alg_mode_blkbits(ob->o_alg, ob->o_mode); -} - -static inline gf_boolean_t -object_alg_atomic(struct object_cipher_info *ob) -{ -    return alg_mode_atomic(ob->o_alg, ob->o_mode); -} - -static inline gf_boolean_t -object_alg_should_pad(struct object_cipher_info *ob) -{ -    return alg_mode_should_pad(ob->o_alg, ob->o_mode); -} - -static inline uint32_t -aes_raw_key_size(struct master_cipher_info *master) -{ -    return master->m_dkey_size >> 3; -} - -static inline struct avec_config * -get_hole_conf(call_frame_t *frame) -{ -    return &(((crypt_local_t *)frame->local)->hole_conf); -} - -static inline struct avec_config * -get_data_conf(call_frame_t *frame) -{ -    return &(((crypt_local_t *)frame->local)->data_conf); -} - -static inline int32_t -get_atom_bits(struct object_cipher_info *object) -{ -    return object->o_block_bits; -} - -static inline int32_t -get_atom_size(struct object_cipher_info *object) -{ -    return 1 << get_atom_bits(object); -} - -static inline int32_t -has_head_block(struct avec_config *conf) -{ -    return conf->off_in_head || (conf->acount == 1 && conf->off_in_tail); -} - -static inline int32_t -has_tail_block(struct avec_config *conf) -{ -    return conf->off_in_tail && conf->acount > 1; -} - -static inline int32_t -has_full_blocks(struct avec_config *conf) -{ -    return conf->nr_full_blocks; -} - -static inline int32_t -should_submit_head_block(struct avec_config *conf) -{ -    return has_head_block(conf) && (conf->cursor == 0); -} - -static inline int32_t -should_submit_tail_block(struct avec_config *conf) -{ -    return has_tail_block(conf) && (conf->cursor == conf->acount - 1); -} - -static inline int32_t -should_submit_full_block(struct avec_config *conf) -{ -    uint32_t start = has_head_block(conf) ? 1 : 0; - -    return has_full_blocks(conf) && conf->cursor >= start && -           conf->cursor < start + conf->nr_full_blocks; -} - -#if DEBUG_CRYPT -static inline void -crypt_check_input_len(size_t len, struct object_cipher_info *object) -{ -    if (object_alg_should_pad(object) && -        (len & (object_alg_blksize(object) - 1))) -        gf_log("crypt", GF_LOG_DEBUG, "bad input len: %d", (int)len); -} - -static inline void -check_head_block(struct avec_config *conf) -{ -    if (!has_head_block(conf)) -        gf_log("crypt", GF_LOG_DEBUG, "not a head atom"); -} - -static inline void -check_tail_block(struct avec_config *conf) -{ -    if (!has_tail_block(conf)) -        gf_log("crypt", GF_LOG_DEBUG, "not a tail atom"); -} - -static inline void -check_full_block(struct avec_config *conf) -{ -    if (!has_full_blocks(conf)) -        gf_log("crypt", GF_LOG_DEBUG, "not a full atom"); -} - -static inline void -check_cursor_head(struct avec_config *conf) -{ -    if (!has_head_block(conf)) -        gf_log("crypt", GF_LOG_DEBUG, "Illegal call of head atom method"); -    else if (conf->cursor != 0) -        gf_log("crypt", GF_LOG_DEBUG, "Cursor (%d) is not at head atom", -               conf->cursor); -} - -static inline void -check_cursor_full(struct avec_config *conf) -{ -    if (!has_full_blocks(conf)) -        gf_log("crypt", GF_LOG_DEBUG, "Illegal call of full atom method"); -    if (has_head_block(conf) && (conf->cursor == 0)) -        gf_log("crypt", GF_LOG_DEBUG, "Cursor is not at full atom"); -} - -/* - * FIXME: use avec->iov_len to check setup - */ -static inline int -data_local_invariant(crypt_local_t *local) -{ -    return 0; -} - -#else -#define crypt_check_input_len(len, object) noop -#define check_head_block(conf) noop -#define check_tail_block(conf) noop -#define check_full_block(conf) noop -#define check_cursor_head(conf) noop -#define check_cursor_full(conf) noop - -#endif /* DEBUG_CRYPT */ - -static inline struct avec_config * -conf_by_type(call_frame_t *frame, atom_data_type dtype) -{ -    struct avec_config *conf = NULL; - -    switch (dtype) { -        case HOLE_ATOM: -            conf = get_hole_conf(frame); -            break; -        case DATA_ATOM: -            conf = get_data_conf(frame); -            break; -        default: -            gf_log("crypt", GF_LOG_DEBUG, "bad atom type"); -    } -    return conf; -} - -static inline uint32_t -nr_calls_head(struct avec_config *conf) -{ -    return has_head_block(conf) ? 1 : 0; -} - -static inline uint32_t -nr_calls_tail(struct avec_config *conf) -{ -    return has_tail_block(conf) ? 1 : 0; -} - -static inline uint32_t -nr_calls_full(struct avec_config *conf) -{ -    switch (conf->type) { -        case HOLE_ATOM: -            return has_full_blocks(conf); -        case DATA_ATOM: -            return has_full_blocks(conf) -                       ? logical_blocks_occupied(0, conf->nr_full_blocks, -                                                 MAX_IOVEC_BITS) -                       : 0; -        default: -            gf_log("crypt", GF_LOG_DEBUG, "bad atom data type"); -            return 0; -    } -} - -static inline uint32_t -nr_calls(struct avec_config *conf) -{ -    return nr_calls_head(conf) + nr_calls_tail(conf) + nr_calls_full(conf); -} - -static inline uint32_t -nr_calls_data(call_frame_t *frame) -{ -    return nr_calls(get_data_conf(frame)); -} - -static inline uint32_t -nr_calls_hole(call_frame_t *frame) -{ -    return nr_calls(get_hole_conf(frame)); -} - -static inline void -get_one_call_nolock(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; - -    ++local->nr_calls; - -    // gf_log("crypt", GF_LOG_DEBUG, "get %d calls", 1); -} - -static inline void -get_one_call(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; - -    LOCK(&local->call_lock); -    get_one_call_nolock(frame); -    UNLOCK(&local->call_lock); -} - -static inline void -get_nr_calls_nolock(call_frame_t *frame, int32_t nr) -{ -    crypt_local_t *local = frame->local; - -    local->nr_calls += nr; - -    // gf_log("crypt", GF_LOG_DEBUG, "get %d calls", nr); -} - -static inline void -get_nr_calls(call_frame_t *frame, int32_t nr) -{ -    crypt_local_t *local = frame->local; - -    LOCK(&local->call_lock); -    get_nr_calls_nolock(frame, nr); -    UNLOCK(&local->call_lock); -} - -static inline int -put_one_call(crypt_local_t *local) -{ -    uint32_t last = 0; - -    LOCK(&local->call_lock); -    if (--local->nr_calls == 0) -        last = 1; - -    // gf_log("crypt", GF_LOG_DEBUG, "put %d calls", 1); - -    UNLOCK(&local->call_lock); -    return last; -} - -static inline int -is_appended_write(call_frame_t *frame) -{ -    crypt_local_t *local = frame->local; -    struct avec_config *conf = get_data_conf(frame); - -    return conf->orig_offset + conf->orig_size > local->old_file_size; -} - -static inline int -is_ordered_mode(call_frame_t *frame) -{ -#if 0 -	crypt_local_t *local = frame->local; -	return local->fop == GF_FOP_FTRUNCATE || -		(local->fop == GF_FOP_WRITE && is_appended_write(frame)); -#endif -    return 1; -} - -static inline int32_t -hole_conv_completed(crypt_local_t *local) -{ -    struct avec_config *conf = &local->hole_conf; -    return conf->cursor == conf->acount; -} - -static inline int32_t -data_write_in_progress(crypt_local_t *local) -{ -    return local->active_setup == DATA_ATOM; -} - -static inline int32_t -parent_is_crypt_xlator(call_frame_t *frame, xlator_t *this) -{ -    return frame->parent->this == this; -} - -static inline linkop_wind_handler_t -linkop_wind_dispatch(glusterfs_fop_t fop) -{ -    switch (fop) { -        case GF_FOP_LINK: -            return link_wind; -        case GF_FOP_UNLINK: -            return unlink_wind; -        case GF_FOP_RENAME: -            return rename_wind; -        default: -            gf_log("crypt", GF_LOG_ERROR, "Bad link operation %d", fop); -            return NULL; -    } -} - -static inline linkop_unwind_handler_t -linkop_unwind_dispatch(glusterfs_fop_t fop) -{ -    switch (fop) { -        case GF_FOP_LINK: -            return link_unwind; -        case GF_FOP_UNLINK: -            return unlink_unwind; -        case GF_FOP_RENAME: -            return rename_unwind; -        default: -            gf_log("crypt", GF_LOG_ERROR, "Bad link operation %d", fop); -            return NULL; -    } -} - -static inline mtd_op_t -linkop_mtdop_dispatch(glusterfs_fop_t fop) -{ -    switch (fop) { -        case GF_FOP_LINK: -            return MTD_APPEND; -        case GF_FOP_UNLINK: -            return MTD_CUT; -        case GF_FOP_RENAME: -            return MTD_OVERWRITE; -        default: -            gf_log("crypt", GF_LOG_WARNING, "Bad link operation %d", fop); -            return MTD_LAST_OP; -    } -} - -#define CRYPT_STACK_UNWIND(fop, frame, params...)                              \ -    do {                                                                       \ -        crypt_local_t *__local = NULL;                                         \ -        if (frame) {                                                           \ -            __local = frame->local;                                            \ -            frame->local = NULL;                                               \ -        }                                                                      \ -        STACK_UNWIND_STRICT(fop, frame, params);                               \ -        if (__local) {                                                         \ -            GF_FREE(__local);                                                  \ -        }                                                                      \ -    } while (0) - -#endif /* __CRYPT_H__ */ - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/data.c b/xlators/encryption/crypt/src/data.c deleted file mode 100644 index 93288b1a414..00000000000 --- a/xlators/encryption/crypt/src/data.c +++ /dev/null @@ -1,715 +0,0 @@ -/* -  Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <glusterfs/defaults.h> -#include "crypt-common.h" -#include "crypt.h" - -static void -set_iv_aes_xts(off_t offset, struct object_cipher_info *object) -{ -    unsigned char *ivec; - -    ivec = object->u.aes_xts.ivec; - -    /* convert the tweak into a little-endian byte -     * array (IEEE P1619/D16, May 2007, section 5.1) -     */ - -    *((uint64_t *)ivec) = htole64(offset); - -    /* ivec is padded with zeroes */ -} - -static int32_t -aes_set_keys_common(unsigned char *raw_key, uint32_t key_size, AES_KEY *keys) -{ -    int32_t ret; - -    ret = AES_set_encrypt_key(raw_key, key_size, &keys[AES_ENCRYPT]); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, "Set encrypt key failed"); -        return ret; -    } -    ret = AES_set_decrypt_key(raw_key, key_size, &keys[AES_DECRYPT]); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, "Set decrypt key failed"); -        return ret; -    } -    return 0; -} - -/* - * set private cipher info for xts mode - */ -static int32_t -set_private_aes_xts(struct crypt_inode_info *info, -                    struct master_cipher_info *master) -{ -    int ret; -    struct object_cipher_info *object = get_object_cinfo(info); -    unsigned char *data_key; -    uint32_t subkey_size; - -    /* init tweak value */ -    memset(object->u.aes_xts.ivec, 0, 16); - -    data_key = GF_CALLOC(1, object->o_dkey_size, gf_crypt_mt_key); -    if (!data_key) -        return ENOMEM; - -    /* -     * retrieve data keying material -     */ -    ret = get_data_file_key(info, master, object->o_dkey_size, data_key); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, "Failed to retrieve data key"); -        GF_FREE(data_key); -        return ret; -    } -    /* -     * parse compound xts key -     */ -    subkey_size = object->o_dkey_size >> 4; /* (xts-key-size-in-bytes / 2) */ -    /* -     * install key for data encryption -     */ -    ret = aes_set_keys_common(data_key, subkey_size << 3, -                              object->u.aes_xts.dkey); -    if (ret) { -        GF_FREE(data_key); -        return ret; -    } -    /* -     * set up key used to encrypt tweaks -     */ -    ret = AES_set_encrypt_key(data_key + subkey_size, object->o_dkey_size / 2, -                              &object->u.aes_xts.tkey); -    if (ret < 0) -        gf_log("crypt", GF_LOG_ERROR, "Set tweak key failed"); - -    GF_FREE(data_key); -    return ret; -} - -static int32_t -aes_xts_init(void) -{ -    cassert(AES_BLOCK_SIZE == (1 << AES_BLOCK_BITS)); -    return 0; -} - -static int32_t -check_key_aes_xts(uint32_t keysize) -{ -    switch (keysize) { -        case 256: -        case 512: -            return 0; -        default: -            break; -    } -    return -1; -} - -static int32_t -encrypt_aes_xts(const unsigned char *from, unsigned char *to, size_t length, -                off_t offset, const int enc, struct object_cipher_info *object) -{ -    XTS128_CONTEXT ctx; -    if (enc) { -        ctx.key1 = &object->u.aes_xts.dkey[AES_ENCRYPT]; -        ctx.block1 = (block128_f)AES_encrypt; -    } else { -        ctx.key1 = &object->u.aes_xts.dkey[AES_DECRYPT]; -        ctx.block1 = (block128_f)AES_decrypt; -    } -    ctx.key2 = &object->u.aes_xts.tkey; -    ctx.block2 = (block128_f)AES_encrypt; - -    return CRYPTO_xts128_encrypt(&ctx, object->u.aes_xts.ivec, from, to, length, -                                 enc); -} - -/* - * Cipher input chunk @from of length @len; - * @to: result of cipher transform; - * @off: offset in a file (must be cblock-aligned); - */ -static void -cipher_data(struct object_cipher_info *object, char *from, char *to, off_t off, -            size_t len, const int enc) -{ -    crypt_check_input_len(len, object); - -#if TRIVIAL_TFM && DEBUG_CRYPT -    return; -#endif -    data_cipher_algs[object->o_alg][object->o_mode].set_iv(off, object); -    data_cipher_algs[object->o_alg][object->o_mode].encrypt( -        (const unsigned char *)from, (unsigned char *)to, len, off, enc, -        object); -} - -#define MAX_CIPHER_CHUNK (1 << 30) - -/* - * Do cipher (encryption/decryption) transform of a - * continuous region of memory. - * - * @len: a number of bytes to transform; - * @buf: data to transform; - * @off: offset in a file, should be block-aligned - *       for atomic cipher modes and ksize-aligned - *       for other modes). - * @dir: direction of transform (encrypt/decrypt). - */ -static void -cipher_region(struct object_cipher_info *object, char *from, char *to, -              off_t off, size_t len, int dir) -{ -    while (len > 0) { -        size_t to_cipher; - -        to_cipher = len; -        if (to_cipher > MAX_CIPHER_CHUNK) -            to_cipher = MAX_CIPHER_CHUNK; - -        /* this will reset IV */ -        cipher_data(object, from, to, off, to_cipher, dir); -        from += to_cipher; -        to += to_cipher; -        off += to_cipher; -        len -= to_cipher; -    } -} - -/* - * Do cipher transform (encryption/decryption) of - * plaintext/ciphertext represented by @vec. - * - * Pre-conditions: @vec represents a continuous piece - * of data in a file at offset @off to be ciphered - * (encrypted/decrypted). - * @count is the number of vec's components. All the - * components must be block-aligned, the caller is - * responsible for this. @dir is "direction" of - * transform (encrypt/decrypt). - */ -static void -cipher_aligned_iov(struct object_cipher_info *object, struct iovec *vec, -                   int count, off_t off, int32_t dir) -{ -    int i; -    int len = 0; - -    for (i = 0; i < count; i++) { -        cipher_region(object, vec[i].iov_base, vec[i].iov_base, off + len, -                      vec[i].iov_len, dir); -        len += vec[i].iov_len; -    } -} - -void -encrypt_aligned_iov(struct object_cipher_info *object, struct iovec *vec, -                    int count, off_t off) -{ -    cipher_aligned_iov(object, vec, count, off, 1); -} - -void -decrypt_aligned_iov(struct object_cipher_info *object, struct iovec *vec, -                    int count, off_t off) -{ -    cipher_aligned_iov(object, vec, count, off, 0); -} - -#if DEBUG_CRYPT -static void -compound_stream(struct iovec *vec, int count, char *buf, off_t skip) -{ -    int i; -    int off = 0; -    for (i = 0; i < count; i++) { -        memcpy(buf + off, vec[i].iov_base + skip, vec[i].iov_len - skip); - -        off += (vec[i].iov_len - skip); -        skip = 0; -    } -} - -static void -check_iovecs(struct iovec *vec, int cnt, struct iovec *avec, int acnt, -             uint32_t off_in_head) -{ -    char *s1, *s2; -    uint32_t size, asize; - -    size = iov_length(vec, cnt); -    asize = iov_length(avec, acnt) - off_in_head; -    if (size != asize) { -        gf_log("crypt", GF_LOG_DEBUG, "size %d is not eq asize %d", size, -               asize); -        return; -    } -    s1 = GF_CALLOC(1, size, gf_crypt_mt_data); -    if (!s1) { -        gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream "); -        return; -    } -    s2 = GF_CALLOC(1, asize, gf_crypt_mt_data); -    if (!s2) { -        GF_FREE(s1); -        gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream "); -        return; -    } -    compound_stream(vec, cnt, s1, 0); -    compound_stream(avec, acnt, s2, off_in_head); -    if (memcmp(s1, s2, size)) -        gf_log("crypt", GF_LOG_DEBUG, "chunks of different data"); -    GF_FREE(s1); -    GF_FREE(s2); -} - -#else -#define check_iovecs(vec, count, avec, avecn, off) noop -#endif /* DEBUG_CRYPT */ - -static char * -data_alloc_block(xlator_t *this, crypt_local_t *local, int32_t block_size) -{ -    struct iobuf *iobuf = NULL; - -    iobuf = iobuf_get2(this->ctx->iobuf_pool, block_size); -    if (!iobuf) { -        gf_log("crypt", GF_LOG_ERROR, "Failed to get iobuf"); -        return NULL; -    } -    if (!local->iobref_data) { -        local->iobref_data = iobref_new(); -        if (!local->iobref_data) { -            gf_log("crypt", GF_LOG_ERROR, "Failed to get iobref"); -            iobuf_unref(iobuf); -            return NULL; -        } -    } -    iobref_add(local->iobref_data, iobuf); -    return iobuf->ptr; -} - -/* - * Compound @avec, which represent the same data - * chunk as @vec, but has aligned components of - * specified block size. Alloc blocks, if needed. - * In particular, incomplete head and tail blocks - * must be allocated. - * Put number of allocated blocks to @num_blocks. - * - * Example: - * - * input: data chunk represented by 4 components - * [AB],[BC],[CD],[DE]; - * output: 5 logical blocks (0, 1, 2, 3, 4). - * - *   A     B       C     D               E - *   *-----*+------*-+---*----+--------+-* - *   |     ||      | |   |    |        | | - * *-+-----+*------+-*---+----*--------*-+------* - * 0        1        2        3        4 - * - * 0 - incomplete compound (head); - * 1, 2 - full compound; - * 3 - full non-compound (the case of reuse); - * 4 - incomplete non-compound (tail). - */ -int32_t -align_iov_by_atoms(xlator_t *this, crypt_local_t *local, -                   struct object_cipher_info *object, -                   struct iovec *vec /* input vector */, -                   int32_t count /* number of vec components */, -                   struct iovec *avec /* aligned vector */, -                   char **blocks /* pool of blocks */, -                   uint32_t *blocks_allocated, struct avec_config *conf) -{ -    int vecn = 0;      /* number of the current component in vec */ -    int avecn = 0;     /* number of the current component in avec */ -    off_t vec_off = 0; /* offset in the current vec component, -                        * i.e. the number of bytes have already -                        * been copied */ -    int32_t block_size = get_atom_size(object); -    size_t to_process; /* number of vec's bytes to copy and(or) re-use */ -    int32_t off_in_head = conf->off_in_head; - -    to_process = iov_length(vec, count); - -    while (to_process > 0) { -        if (off_in_head || vec[vecn].iov_len - vec_off < block_size) { -            /* -             * less than block_size: -             * the case of incomplete (head or tail), -             * or compound block -             */ -            size_t copied = 0; -            /* -             * populate the pool with a new block -             */ -            blocks[*blocks_allocated] = data_alloc_block(this, local, -                                                         block_size); -            if (!blocks[*blocks_allocated]) -                return -ENOMEM; -            memset(blocks[*blocks_allocated], 0, off_in_head); -            /* -             * fill the block with vec components -             */ -            do { -                size_t to_copy; - -                to_copy = vec[vecn].iov_len - vec_off; -                if (to_copy > block_size - off_in_head) -                    to_copy = block_size - off_in_head; - -                memcpy(blocks[*blocks_allocated] + off_in_head + copied, -                       vec[vecn].iov_base + vec_off, to_copy); - -                copied += to_copy; -                to_process -= to_copy; - -                vec_off += to_copy; -                if (vec_off == vec[vecn].iov_len) { -                    /* finished with this vecn */ -                    vec_off = 0; -                    vecn++; -                } -            } while (copied < (block_size - off_in_head) && to_process > 0); -            /* -             * update avec -             */ -            avec[avecn].iov_len = off_in_head + copied; -            avec[avecn].iov_base = blocks[*blocks_allocated]; - -            (*blocks_allocated)++; -            off_in_head = 0; -        } else { -            /* -             * the rest of the current vec component -             * is not less than block_size, so reuse -             * the memory buffer of the component. -             */ -            size_t to_reuse; -            to_reuse = (to_process > block_size ? block_size : to_process); -            avec[avecn].iov_len = to_reuse; -            avec[avecn].iov_base = vec[vecn].iov_base + vec_off; - -            vec_off += to_reuse; -            if (vec_off == vec[vecn].iov_len) { -                /* finished with this vecn */ -                vec_off = 0; -                vecn++; -            } -            to_process -= to_reuse; -        } -        avecn++; -    } -    check_iovecs(vec, count, avec, avecn, conf->off_in_head); -    return 0; -} - -/* - * allocate and setup aligned vector for data submission - * Pre-condition: @conf is set. - */ -int32_t -set_config_avec_data(xlator_t *this, crypt_local_t *local, -                     struct avec_config *conf, -                     struct object_cipher_info *object, struct iovec *vec, -                     int32_t vec_count) -{ -    int32_t ret = ENOMEM; -    struct iovec *avec; -    char **pool; -    uint32_t blocks_in_pool = 0; - -    conf->type = DATA_ATOM; - -    avec = GF_CALLOC(conf->acount, sizeof(*avec), gf_crypt_mt_iovec); -    if (!avec) -        return ret; -    pool = GF_CALLOC(conf->acount, sizeof(*pool), gf_crypt_mt_char); -    if (!pool) { -        GF_FREE(avec); -        return ret; -    } -    if (!vec) { -        /* -         * degenerated case: no data -         */ -        pool[0] = data_alloc_block(this, local, get_atom_size(object)); -        if (!pool[0]) -            goto free; -        blocks_in_pool = 1; -        avec->iov_base = pool[0]; -        avec->iov_len = conf->off_in_tail; -    } else { -        ret = align_iov_by_atoms(this, local, object, vec, vec_count, avec, -                                 pool, &blocks_in_pool, conf); -        if (ret) -            goto free; -    } -    conf->avec = avec; -    conf->pool = pool; -    conf->blocks_in_pool = blocks_in_pool; -    return 0; -free: -    GF_FREE(avec); -    GF_FREE(pool); -    return ret; -} - -/* - * allocate and setup aligned vector for hole submission - */ -int32_t -set_config_avec_hole(xlator_t *this, crypt_local_t *local, -                     struct avec_config *conf, -                     struct object_cipher_info *object, glusterfs_fop_t fop) -{ -    uint32_t i, idx; -    struct iovec *avec; -    char **pool; -    uint32_t num_blocks; -    uint32_t blocks_in_pool = 0; - -    conf->type = HOLE_ATOM; - -    num_blocks = conf->acount - -                 (conf->nr_full_blocks ? conf->nr_full_blocks - 1 : 0); - -    switch (fop) { -        case GF_FOP_WRITE: -            /* -             * hole goes before data -             */ -            if (num_blocks == 1 && conf->off_in_tail != 0) -                /* -                 * we won't submit a hole which fits into -                 * a data atom: this part of hole will be -                 * submitted with data write -                 */ -                return 0; -            break; -        case GF_FOP_FTRUNCATE: -            /* -             * expanding truncate, hole goes after data, -             * and will be submitted in any case. -             */ -            break; -        default: -            gf_log("crypt", GF_LOG_WARNING, "bad file operation %d", fop); -            return 0; -    } -    avec = GF_CALLOC(num_blocks, sizeof(*avec), gf_crypt_mt_iovec); -    if (!avec) -        return ENOMEM; -    pool = GF_CALLOC(num_blocks, sizeof(*pool), gf_crypt_mt_char); -    if (!pool) { -        GF_FREE(avec); -        return ENOMEM; -    } -    for (i = 0; i < num_blocks; i++) { -        pool[i] = data_alloc_block(this, local, get_atom_size(object)); -        if (pool[i] == NULL) -            goto free; -        blocks_in_pool++; -    } -    if (has_head_block(conf)) { -        /* set head block */ -        idx = 0; -        avec[idx].iov_base = pool[idx]; -        avec[idx].iov_len = get_atom_size(object); -        memset(avec[idx].iov_base + conf->off_in_head, 0, -               get_atom_size(object) - conf->off_in_head); -    } -    if (has_tail_block(conf)) { -        /* set tail block */ -        idx = num_blocks - 1; -        avec[idx].iov_base = pool[idx]; -        avec[idx].iov_len = get_atom_size(object); -        memset(avec[idx].iov_base, 0, conf->off_in_tail); -    } -    if (has_full_blocks(conf)) { -        /* set full block */ -        idx = conf->off_in_head ? 1 : 0; -        avec[idx].iov_base = pool[idx]; -        avec[idx].iov_len = get_atom_size(object); -        /* -         * since we re-use the buffer, -         * zeroes will be set every time -         * before encryption, see submit_full() -         */ -    } -    conf->avec = avec; -    conf->pool = pool; -    conf->blocks_in_pool = blocks_in_pool; -    return 0; -free: -    GF_FREE(avec); -    GF_FREE(pool); -    return ENOMEM; -} - -/* A helper for setting up config of partial atoms (which - * participate in read-modify-write sequence). - * - * Calculate and setup precise amount of "extra-bytes" - * that should be uptodated at the end of partial (not - * necessarily tail!) block. - * - * Pre-condition: local->old_file_size is valid! - * @conf contains setup, which is enough for correct calculation - * of has_tail_block(), ->get_offset(). - */ -void -set_gap_at_end(call_frame_t *frame, struct object_cipher_info *object, -               struct avec_config *conf, atom_data_type dtype) -{ -    uint32_t to_block; -    crypt_local_t *local = frame->local; -    uint64_t old_file_size = local->old_file_size; -    struct rmw_atom *partial = atom_by_types( -        dtype, has_tail_block(conf) ? TAIL_ATOM : HEAD_ATOM); - -    if (old_file_size <= partial->offset_at(frame, object)) -        to_block = 0; -    else { -        to_block = old_file_size - partial->offset_at(frame, object); -        if (to_block > get_atom_size(object)) -            to_block = get_atom_size(object); -    } -    if (to_block > conf->off_in_tail) -        conf->gap_in_tail = to_block - conf->off_in_tail; -    else -        /* -         * nothing to uptodate -         */ -        conf->gap_in_tail = 0; -} - -/* - * fill struct avec_config with offsets layouts - */ -void -set_config_offsets(call_frame_t *frame, xlator_t *this, uint64_t offset, -                   uint64_t count, atom_data_type dtype, int32_t set_gap) -{ -    crypt_local_t *local; -    struct object_cipher_info *object; -    struct avec_config *conf; -    uint32_t resid; - -    uint32_t atom_size; -    uint32_t atom_bits; - -    size_t orig_size; -    off_t orig_offset; -    size_t expanded_size; -    off_t aligned_offset; - -    uint32_t off_in_head = 0; -    uint32_t off_in_tail = 0; -    uint32_t nr_full_blocks; -    int32_t size_full_blocks; - -    uint32_t acount; /* number of aligned components to write. -                      * The same as number of occupied logical -                      * blocks (atoms) -                      */ -    local = frame->local; -    object = &local->info->cinfo; -    conf = (dtype == DATA_ATOM ? get_data_conf(frame) : get_hole_conf(frame)); - -    orig_offset = offset; -    orig_size = count; - -    atom_size = get_atom_size(object); -    atom_bits = get_atom_bits(object); - -    /* -     * Round-down the start, -     * round-up the end. -     */ -    resid = offset & (uint64_t)(atom_size - 1); - -    if (resid) -        off_in_head = resid; -    aligned_offset = offset - off_in_head; -    expanded_size = orig_size + off_in_head; - -    /* calculate tail, -       expand size forward  */ -    resid = (offset + orig_size) & (uint64_t)(atom_size - 1); - -    if (resid) { -        off_in_tail = resid; -        expanded_size += (atom_size - off_in_tail); -    } -    /* -     * calculate number of occupied blocks -     */ -    acount = expanded_size >> atom_bits; -    /* -     * calculate number of full blocks -     */ -    size_full_blocks = expanded_size; -    if (off_in_head) -        size_full_blocks -= atom_size; -    if (off_in_tail && size_full_blocks > 0) -        size_full_blocks -= atom_size; -    nr_full_blocks = size_full_blocks >> atom_bits; - -    conf->atom_size = atom_size; -    conf->orig_size = orig_size; -    conf->orig_offset = orig_offset; -    conf->expanded_size = expanded_size; -    conf->aligned_offset = aligned_offset; - -    conf->off_in_head = off_in_head; -    conf->off_in_tail = off_in_tail; -    conf->nr_full_blocks = nr_full_blocks; -    conf->acount = acount; -    /* -     * Finally, calculate precise amount of -     * "extra-bytes" that should be uptodated -     * at the end. -     * Only if RMW is expected. -     */ -    if (off_in_tail && set_gap) -        set_gap_at_end(frame, object, conf, dtype); -} - -struct data_cipher_alg data_cipher_algs[LAST_CIPHER_ALG][LAST_CIPHER_MODE] = { -    [AES_CIPHER_ALG][XTS_CIPHER_MODE] = {.atomic = _gf_true, -                                         .should_pad = _gf_true, -                                         .blkbits = AES_BLOCK_BITS, -                                         .init = aes_xts_init, -                                         .set_private = set_private_aes_xts, -                                         .check_key = check_key_aes_xts, -                                         .set_iv = set_iv_aes_xts, -                                         .encrypt = encrypt_aes_xts}}; - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/keys.c b/xlators/encryption/crypt/src/keys.c deleted file mode 100644 index 92a4d471f58..00000000000 --- a/xlators/encryption/crypt/src/keys.c +++ /dev/null @@ -1,284 +0,0 @@ -/* -  Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <glusterfs/defaults.h> -#include "crypt-common.h" -#include "crypt.h" - -/* Key hierarchy - -                   +----------------+ -                   | MASTER_VOL_KEY | -                   +-------+--------+ -                           | -                           | -          +----------------+----------------+ -          |                |                | -          |                |                | -  +-------+------+ +-------+-------+ +------+--------+ -  | NMTD_VOL_KEY | | EMTD_FILE_KEY | | DATA_FILE_KEY | -  +-------+------+ +---------------+ +---------------+ -          | -          | -  +-------+-------+ -  | NMTD_LINK_KEY | -  +---------------+ - - */ - -#if DEBUG_CRYPT -static void -check_prf_iters(uint32_t num_iters) -{ -    if (num_iters == 0) -        gf_log("crypt", GF_LOG_DEBUG, "bad number of prf iterations : %d", -               num_iters); -} -#else -#define check_prf_iters(num_iters) noop -#endif /* DEBUG_CRYPT */ - -unsigned char crypt_fake_oid[16] = {0, 0, 0, 0, 0, 0, 0, 0, -                                    0, 0, 0, 0, 0, 0, 0, 0}; - -/* - * derive key in the counter mode using - * sha256-based HMAC as PRF, see - * NIST Special Publication 800-108, 5.1) - */ - -#define PRF_OUTPUT_SIZE SHA256_DIGEST_LENGTH - -static int32_t -kderive_init(struct kderive_context *ctx, -             const unsigned char *pkey,  /* parent key */ -             uint32_t pkey_size,         /* parent key size */ -             const unsigned char *idctx, /* id-context */ -             uint32_t idctx_size, crypt_key_type type /* type of child key */) -{ -    unsigned char *pos; -    uint32_t llen = strlen(crypt_keys[type].label); -    /* -     * Compoud the fixed input data for KDF: -     * [i]_2 || Label || 0x00 || Id-Context || [L]_2), -     * NIST SP 800-108, 5.1 -     */ -    ctx->fid_len = sizeof(uint32_t) + llen + 1 + idctx_size + sizeof(uint32_t); - -    ctx->fid = GF_CALLOC(ctx->fid_len, 1, gf_crypt_mt_key); -    if (!ctx->fid) -        return ENOMEM; -    ctx->out_len = round_up(crypt_keys[type].len >> 3, PRF_OUTPUT_SIZE); -    ctx->out = GF_CALLOC(ctx->out_len, 1, gf_crypt_mt_key); -    if (!ctx->out) { -        GF_FREE(ctx->fid); -        return ENOMEM; -    } -    ctx->pkey = pkey; -    ctx->pkey_len = pkey_size; -    ctx->ckey_len = crypt_keys[type].len; - -    pos = ctx->fid; - -    /* counter will be set up in kderive_rfn() */ -    pos += sizeof(uint32_t); - -    memcpy(pos, crypt_keys[type].label, llen); -    pos += llen; - -    /* set up zero octet */ -    *pos = 0; -    pos += 1; - -    memcpy(pos, idctx, idctx_size); -    pos += idctx_size; - -    *((uint32_t *)pos) = htobe32(ctx->ckey_len); - -    return 0; -} - -static void -kderive_update(struct kderive_context *ctx) -{ -    uint32_t i; -#if (OPENSSL_VERSION_NUMBER < 0x1010002f) -    HMAC_CTX hctx; -#endif -    HMAC_CTX *phctx = NULL; -    unsigned char *pos = ctx->out; -    uint32_t *p_iter = (uint32_t *)ctx->fid; -    uint32_t num_iters = ctx->out_len / PRF_OUTPUT_SIZE; - -    check_prf_iters(num_iters); - -#if (OPENSSL_VERSION_NUMBER < 0x1010002f) -    HMAC_CTX_init(&hctx); -    phctx = &hctx; -#else -    phctx = HMAC_CTX_new(); -    /* I guess we presume it was successful? */ -#endif -    for (i = 0; i < num_iters; i++) { -        /* -         * update the iteration number in the fid -         */ -        *p_iter = htobe32(i); -        HMAC_Init_ex(phctx, ctx->pkey, ctx->pkey_len >> 3, EVP_sha256(), NULL); -        HMAC_Update(phctx, ctx->fid, ctx->fid_len); -        HMAC_Final(phctx, pos, NULL); - -        pos += PRF_OUTPUT_SIZE; -    } -#if (OPENSSL_VERSION_NUMBER < 0x1010002f) -    HMAC_CTX_cleanup(phctx); -#else -    HMAC_CTX_free(phctx); -#endif -} - -static void -kderive_final(struct kderive_context *ctx, unsigned char *child) -{ -    memcpy(child, ctx->out, ctx->ckey_len >> 3); -    GF_FREE(ctx->fid); -    GF_FREE(ctx->out); -    memset(ctx, 0, sizeof(*ctx)); -} - -/* - * derive per-volume key for object ids aithentication - */ -int32_t -get_nmtd_vol_key(struct master_cipher_info *master) -{ -    int32_t ret; -    struct kderive_context ctx; - -    ret = kderive_init(&ctx, master->m_key, master_key_size(), crypt_fake_oid, -                       sizeof(uuid_t), NMTD_VOL_KEY); -    if (ret) -        return ret; -    kderive_update(&ctx); -    kderive_final(&ctx, master->m_nmtd_key); -    return 0; -} - -/* - * derive per-link key for aithentication of non-encrypted - * meta-data (nmtd) - */ -int32_t -get_nmtd_link_key(loc_t *loc, struct master_cipher_info *master, -                  unsigned char *result) -{ -    int32_t ret; -    struct kderive_context ctx; - -    ret = kderive_init(&ctx, master->m_nmtd_key, nmtd_vol_key_size(), -                       (const unsigned char *)loc->path, strlen(loc->path), -                       NMTD_LINK_KEY); -    if (ret) -        return ret; -    kderive_update(&ctx); -    kderive_final(&ctx, result); -    return 0; -} - -/* - * derive per-file key for encryption and authentication - * of encrypted part of metadata (emtd) - */ -int32_t -get_emtd_file_key(struct crypt_inode_info *info, -                  struct master_cipher_info *master, unsigned char *result) -{ -    int32_t ret; -    struct kderive_context ctx; - -    ret = kderive_init(&ctx, master->m_key, master_key_size(), info->oid, -                       sizeof(uuid_t), EMTD_FILE_KEY); -    if (ret) -        return ret; -    kderive_update(&ctx); -    kderive_final(&ctx, result); -    return 0; -} - -static int32_t -data_key_type_by_size(uint32_t keysize, crypt_key_type *type) -{ -    int32_t ret = 0; -    switch (keysize) { -        case 256: -            *type = DATA_FILE_KEY_256; -            break; -        case 512: -            *type = DATA_FILE_KEY_512; -            break; -        default: -            gf_log("crypt", GF_LOG_ERROR, "Unsupported data key size %d", -                   keysize); -            ret = ENOTSUP; -            break; -    } -    return ret; -} - -/* - * derive per-file key for data encryption - */ -int32_t -get_data_file_key(struct crypt_inode_info *info, -                  struct master_cipher_info *master, uint32_t keysize, -                  unsigned char *key) -{ -    int32_t ret; -    struct kderive_context ctx; -    crypt_key_type type; - -    ret = data_key_type_by_size(keysize, &type); -    if (ret) -        return ret; -    ret = kderive_init(&ctx, master->m_key, master_key_size(), info->oid, -                       sizeof(uuid_t), type); -    if (ret) -        return ret; -    kderive_update(&ctx); -    kderive_final(&ctx, key); -    return 0; -} - -/* - * NOTE: Don't change existing keys: it will break compatibility; - */ -struct crypt_key crypt_keys[LAST_KEY_TYPE] = { -    [MASTER_VOL_KEY] = -        { -            .len = MASTER_VOL_KEY_SIZE << 3, -            .label = "volume-master", -        }, -    [NMTD_VOL_KEY] = {.len = NMTD_VOL_KEY_SIZE << 3, -                      .label = "volume-nmtd-key-generation"}, -    [NMTD_LINK_KEY] = {.len = 128, .label = "link-nmtd-authentication"}, -    [EMTD_FILE_KEY] = {.len = 128, .label = "file-emtd-encryption-and-auth"}, -    [DATA_FILE_KEY_256] = {.len = 256, .label = "file-data-encryption-256"}, -    [DATA_FILE_KEY_512] = {.len = 512, .label = "file-data-encryption-512"}}; - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/metadata.c b/xlators/encryption/crypt/src/metadata.c deleted file mode 100644 index 120ae62f777..00000000000 --- a/xlators/encryption/crypt/src/metadata.c +++ /dev/null @@ -1,575 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <glusterfs/defaults.h> -#include "crypt-common.h" -#include "crypt.h" -#include "metadata.h" - -int32_t -alloc_format(crypt_local_t *local, size_t size) -{ -    if (size > 0) { -        local->format = GF_CALLOC(1, size, gf_crypt_mt_mtd); -        if (!local->format) -            return ENOMEM; -    } -    local->format_size = size; -    return 0; -} - -int32_t -alloc_format_create(crypt_local_t *local) -{ -    return alloc_format(local, new_format_size()); -} - -void -free_format(crypt_local_t *local) -{ -    GF_FREE(local->format); -} - -/* - * Check compatibility with extracted metadata - */ -static int32_t -check_file_metadata(struct crypt_inode_info *info) -{ -    struct object_cipher_info *object = &info->cinfo; - -    if (info->nr_minor != CRYPT_XLATOR_ID) { -        gf_log("crypt", GF_LOG_WARNING, "unsupported minor subversion %d", -               info->nr_minor); -        return EINVAL; -    } -    if (object->o_alg > LAST_CIPHER_ALG) { -        gf_log("crypt", GF_LOG_WARNING, "unsupported cipher algorithm %d", -               object->o_alg); -        return EINVAL; -    } -    if (object->o_mode > LAST_CIPHER_MODE) { -        gf_log("crypt", GF_LOG_WARNING, "unsupported cipher mode %d", -               object->o_mode); -        return EINVAL; -    } -    if (object->o_block_bits < CRYPT_MIN_BLOCK_BITS || -        object->o_block_bits > CRYPT_MAX_BLOCK_BITS) { -        gf_log("crypt", GF_LOG_WARNING, "unsupported block bits %d", -               object->o_block_bits); -        return EINVAL; -    } -    /* TBD: check data key size */ -    return 0; -} - -static size_t -format_size_v1(mtd_op_t op, size_t old_size) -{ -    switch (op) { -        case MTD_CREATE: -            return sizeof(struct mtd_format_v1); -        case MTD_OVERWRITE: -            return old_size; -        case MTD_APPEND: -            return old_size + NMTD_8_MAC_SIZE; -        case MTD_CUT: -            if (old_size > sizeof(struct mtd_format_v1)) -                return old_size - NMTD_8_MAC_SIZE; -            else -                return 0; -        default: -            gf_log("crypt", GF_LOG_WARNING, "Bad mtd operation"); -            return 0; -    } -} - -/* - * Calculate size of the updated format string. - * Returned zero means that we don't need to update the format string. - */ -size_t -format_size(mtd_op_t op, size_t old_size) -{ -    size_t versioned; - -    versioned = mtd_loaders[current_mtd_loader()].format_size( -        op, old_size - sizeof(struct crypt_format)); -    if (versioned != 0) -        return versioned + sizeof(struct crypt_format); -    return 0; -} - -/* - * size of the format string of newly created file (nr_links = 1) - */ -size_t -new_format_size(void) -{ -    return format_size(MTD_CREATE, 0); -} - -/* - * Calculate per-link MAC by pathname - */ -static int32_t -calc_link_mac_v1(struct mtd_format_v1 *fmt, loc_t *loc, unsigned char *result, -                 struct crypt_inode_info *info, -                 struct master_cipher_info *master) -{ -    int32_t ret; -    unsigned char nmtd_link_key[16]; -    CMAC_CTX *cctx; -    size_t len; - -    ret = get_nmtd_link_key(loc, master, nmtd_link_key); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, "Can not get nmtd link key"); -        return -1; -    } -    cctx = CMAC_CTX_new(); -    if (!cctx) { -        gf_log("crypt", GF_LOG_ERROR, "CMAC_CTX_new failed"); -        return -1; -    } -    ret = CMAC_Init(cctx, nmtd_link_key, sizeof(nmtd_link_key), -                    EVP_aes_128_cbc(), 0); -    if (!ret) { -        gf_log("crypt", GF_LOG_ERROR, "CMAC_Init failed"); -        CMAC_CTX_free(cctx); -        return -1; -    } -    ret = CMAC_Update(cctx, get_NMTD_V1(info), SIZE_OF_NMTD_V1); -    if (!ret) { -        gf_log("crypt", GF_LOG_ERROR, "CMAC_Update failed"); -        CMAC_CTX_free(cctx); -        return -1; -    } -    ret = CMAC_Final(cctx, result, &len); -    CMAC_CTX_free(cctx); -    if (!ret) { -        gf_log("crypt", GF_LOG_ERROR, "CMAC_Final failed"); -        return -1; -    } -    return 0; -} - -/* - * Create per-link MAC of index @idx by pathname - */ -static int32_t -create_link_mac_v1(struct mtd_format_v1 *fmt, uint32_t idx, loc_t *loc, -                   struct crypt_inode_info *info, -                   struct master_cipher_info *master) -{ -    int32_t ret; -    unsigned char *mac; -    unsigned char cmac[16]; - -    mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC; - -    ret = calc_link_mac_v1(fmt, loc, cmac, info, master); -    if (ret) -        return -1; -    memcpy(mac, cmac, SIZE_OF_NMTD_V1_MAC); -    return 0; -} - -static int32_t -create_format_v1(unsigned char *wire, loc_t *loc, struct crypt_inode_info *info, -                 struct master_cipher_info *master) -{ -    int32_t ret; -    struct mtd_format_v1 *fmt; -    unsigned char mtd_key[16]; -    AES_KEY EMTD_KEY; -    unsigned char nmtd_link_key[16]; -    uint32_t ad; -    GCM128_CONTEXT *gctx; - -    fmt = (struct mtd_format_v1 *)wire; - -    fmt->minor_id = info->nr_minor; -    fmt->alg_id = AES_CIPHER_ALG; -    fmt->dkey_factor = master->m_dkey_size >> KEY_FACTOR_BITS; -    fmt->block_bits = master->m_block_bits; -    fmt->mode_id = master->m_mode; -    /* -     * retrieve keys for the parts of metadata -     */ -    ret = get_emtd_file_key(info, master, mtd_key); -    if (ret) -        return ret; -    ret = get_nmtd_link_key(loc, master, nmtd_link_key); -    if (ret) -        return ret; - -    AES_set_encrypt_key(mtd_key, sizeof(mtd_key) * 8, &EMTD_KEY); - -    gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt); - -    /* TBD: Check return values */ - -    CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t)); - -    ad = htole32(MTD_LOADER_V1); -    ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad)); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed"); -        CRYPTO_gcm128_release(gctx); -        return ret; -    } -    ret = CRYPTO_gcm128_encrypt(gctx, get_EMTD_V1(fmt), get_EMTD_V1(fmt), -                                SIZE_OF_EMTD_V1); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_encrypt failed"); -        CRYPTO_gcm128_release(gctx); -        return ret; -    } -    /* -     * set MAC of encrypted part of metadata -     */ -    CRYPTO_gcm128_tag(gctx, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC); -    CRYPTO_gcm128_release(gctx); -    /* -     * set the first MAC of non-encrypted part of metadata -     */ -    return create_link_mac_v1(fmt, 0, loc, info, master); -} - -/* - * Called by fops: - * ->create(); - * ->link(); - * - * Pack common and version-specific parts of file's metadata - * Pre-conditions: @info contains valid object-id. - */ -int32_t -create_format(unsigned char *wire, loc_t *loc, struct crypt_inode_info *info, -              struct master_cipher_info *master) -{ -    struct crypt_format *fmt = (struct crypt_format *)wire; - -    fmt->loader_id = current_mtd_loader(); - -    wire += sizeof(struct crypt_format); -    return mtd_loaders[current_mtd_loader()].create_format(wire, loc, info, -                                                           master); -} - -/* - * Append or overwrite per-link mac of @mac_idx index - * in accordance with the new pathname - */ -int32_t -appov_link_mac_v1(unsigned char *new, unsigned char *old, uint32_t old_size, -                  int32_t mac_idx, loc_t *loc, struct crypt_inode_info *info, -                  struct master_cipher_info *master, crypt_local_t *local) -{ -    memcpy(new, old, old_size); -    return create_link_mac_v1((struct mtd_format_v1 *)new, mac_idx, loc, info, -                              master); -} - -/* - * Cut per-link mac of @mac_idx index - */ -static int32_t -cut_link_mac_v1(unsigned char *new, unsigned char *old, uint32_t old_size, -                int32_t mac_idx, loc_t *loc, struct crypt_inode_info *info, -                struct master_cipher_info *master, crypt_local_t *local) -{ -    memcpy(new, old, -           sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * (mac_idx - 1)); - -    memcpy( -        new + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE *(mac_idx - 1), -        old + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx, -        old_size - (sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx)); -    return 0; -} - -int32_t -update_format_v1(unsigned char *new, unsigned char *old, size_t old_len, -                 int32_t mac_idx, /* of old name */ -                 mtd_op_t op, loc_t *loc, struct crypt_inode_info *info, -                 struct master_cipher_info *master, crypt_local_t *local) -{ -    switch (op) { -        case MTD_APPEND: -            mac_idx = 1 + (old_len - sizeof(struct mtd_format_v1)) / 8; -        case MTD_OVERWRITE: -            return appov_link_mac_v1(new, old, old_len, mac_idx, loc, info, -                                     master, local); -        case MTD_CUT: -            return cut_link_mac_v1(new, old, old_len, mac_idx, loc, info, -                                   master, local); -        default: -            gf_log("crypt", GF_LOG_ERROR, "Bad  mtd operation %d", op); -            return -1; -    } -} - -/* - * Called by fops: - * - * ->link() - * ->unlink() - * ->rename() - * - */ -int32_t -update_format(unsigned char *new, unsigned char *old, size_t old_len, -              int32_t mac_idx, mtd_op_t op, loc_t *loc, -              struct crypt_inode_info *info, struct master_cipher_info *master, -              crypt_local_t *local) -{ -    if (!new) -        return 0; -    memcpy(new, old, sizeof(struct crypt_format)); - -    old += sizeof(struct crypt_format); -    new += sizeof(struct crypt_format); -    old_len -= sizeof(struct crypt_format); - -    return mtd_loaders[current_mtd_loader()].update_format( -        new, old, old_len, mac_idx, op, loc, info, master, local); -} - -/* - * Perform preliminary checks of found metadata - * Return < 0 on errors; - * Return number of object-id MACs (>= 1) on success - */ -int32_t -check_format_v1(uint32_t len, unsigned char *wire) -{ -    uint32_t nr_links; - -    if (len < sizeof(struct mtd_format_v1)) { -        gf_log("crypt", GF_LOG_ERROR, "v1-loader: bad metadata size %d", len); -        goto error; -    } -    len -= sizeof(struct mtd_format_v1); -    if (len % sizeof(nmtd_8_mac_t)) { -        gf_log("crypt", GF_LOG_ERROR, "v1-loader: bad metadata format"); -        goto error; -    } -    nr_links = 1 + len / sizeof(nmtd_8_mac_t); -    if (nr_links > _POSIX_LINK_MAX) -        goto error; -    return nr_links; -error: -    return EIO; -} - -/* - * Verify per-link MAC specified by index @idx - * - * return: - * -1 on errors; - *  0 on failed verification; - *  1 on successful verification - */ -static int32_t -verify_link_mac_v1(struct mtd_format_v1 *fmt, -                   uint32_t idx /* index of the mac to verify */, loc_t *loc, -                   struct crypt_inode_info *info, -                   struct master_cipher_info *master) -{ -    int32_t ret; -    unsigned char *mac; -    unsigned char cmac[16]; - -    mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC; - -    ret = calc_link_mac_v1(fmt, loc, cmac, info, master); -    if (ret) -        return -1; -    if (memcmp(cmac, mac, SIZE_OF_NMTD_V1_MAC)) -        return 0; -    return 1; -} - -/* - * Lookup per-link MAC by pathname. - * - * return index of the MAC, if it was found; - * return < 0 on errors, or if the MAC wasn't found - */ -static int32_t -lookup_link_mac_v1(struct mtd_format_v1 *fmt, uint32_t nr_macs, loc_t *loc, -                   struct crypt_inode_info *info, -                   struct master_cipher_info *master) -{ -    int32_t ret; -    uint32_t idx; - -    for (idx = 0; idx < nr_macs; idx++) { -        ret = verify_link_mac_v1(fmt, idx, loc, info, master); -        if (ret < 0) -            return ret; -        if (ret > 0) -            return idx; -    } -    return -ENOENT; -} - -/* - * Extract version-specific part of metadata - */ -static int32_t -open_format_v1(unsigned char *wire, int32_t len, loc_t *loc, -               struct crypt_inode_info *info, struct master_cipher_info *master, -               crypt_local_t *local, gf_boolean_t load_info) -{ -    int32_t ret; -    int32_t num_nmtd_macs; -    struct mtd_format_v1 *fmt; -    unsigned char mtd_key[16]; -    AES_KEY EMTD_KEY; -    GCM128_CONTEXT *gctx; -    uint32_t ad; -    emtd_8_mac_t gmac; -    struct object_cipher_info *object; - -    num_nmtd_macs = check_format_v1(len, wire); -    if (num_nmtd_macs <= 0) -        return EIO; - -    ret = lookup_link_mac_v1((struct mtd_format_v1 *)wire, num_nmtd_macs, loc, -                             info, master); -    if (ret < 0) { -        gf_log("crypt", GF_LOG_ERROR, "NMTD verification failed"); -        return EINVAL; -    } - -    local->mac_idx = ret; -    if (load_info == _gf_false) -        /* the case of partial open */ -        return 0; - -    fmt = GF_MALLOC(len, gf_crypt_mt_mtd); -    if (!fmt) -        return ENOMEM; -    memcpy(fmt, wire, len); - -    object = &info->cinfo; - -    ret = get_emtd_file_key(info, master, mtd_key); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, "Can not retrieve metadata key"); -        goto out; -    } -    /* -     * decrypt encrypted meta-data -     */ -    ret = AES_set_encrypt_key(mtd_key, sizeof(mtd_key) * 8, &EMTD_KEY); -    if (ret < 0) { -        gf_log("crypt", GF_LOG_ERROR, "Can not set encrypt key"); -        ret = EIO; -        goto out; -    } -    gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt); -    if (!gctx) { -        gf_log("crypt", GF_LOG_ERROR, "Can not alloc gcm context"); -        ret = ENOMEM; -        goto out; -    } -    CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t)); - -    ad = htole32(MTD_LOADER_V1); -    ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad)); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed"); -        CRYPTO_gcm128_release(gctx); -        ret = EIO; -        goto out; -    } -    ret = CRYPTO_gcm128_decrypt(gctx, get_EMTD_V1(fmt), get_EMTD_V1(fmt), -                                SIZE_OF_EMTD_V1); -    if (ret) { -        gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_decrypt failed"); -        CRYPTO_gcm128_release(gctx); -        ret = EIO; -        goto out; -    } -    /* -     * verify metadata -     */ -    CRYPTO_gcm128_tag(gctx, gmac, sizeof(gmac)); -    CRYPTO_gcm128_release(gctx); -    if (memcmp(gmac, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC)) { -        gf_log("crypt", GF_LOG_ERROR, "EMTD verification failed"); -        ret = EINVAL; -        goto out; -    } -    /* -     * load verified metadata to the private part of inode -     */ -    info->nr_minor = fmt->minor_id; - -    object->o_alg = fmt->alg_id; -    object->o_dkey_size = fmt->dkey_factor << KEY_FACTOR_BITS; -    object->o_block_bits = fmt->block_bits; -    object->o_mode = fmt->mode_id; - -    ret = check_file_metadata(info); -out: -    GF_FREE(fmt); -    return ret; -} - -/* - * perform metadata authentication against @loc->path; - * extract crypt-specific attribute and populate @info - * with them (optional) - */ -int32_t -open_format(unsigned char *str, int32_t len, loc_t *loc, -            struct crypt_inode_info *info, struct master_cipher_info *master, -            crypt_local_t *local, gf_boolean_t load_info) -{ -    struct crypt_format *fmt; -    if (len < sizeof(*fmt)) { -        gf_log("crypt", GF_LOG_ERROR, "Bad core format"); -        return EIO; -    } -    fmt = (struct crypt_format *)str; - -    if (fmt->loader_id >= LAST_MTD_LOADER) { -        gf_log("crypt", GF_LOG_ERROR, "Unsupported loader id %d", -               fmt->loader_id); -        return EINVAL; -    } -    str += sizeof(*fmt); -    len -= sizeof(*fmt); - -    return mtd_loaders[fmt->loader_id].open_format(str, len, loc, info, master, -                                                   local, load_info); -} - -struct crypt_mtd_loader mtd_loaders[LAST_MTD_LOADER] = { -    [MTD_LOADER_V1] = {.format_size = format_size_v1, -                       .create_format = create_format_v1, -                       .open_format = open_format_v1, -                       .update_format = update_format_v1}}; - -/* -  Local variables: -  c-indentation-style: "K&R" -  mode-name: "LC" -  c-basic-offset: 8 -  tab-width: 8 -  fill-column: 80 -  scroll-step: 1 -  End: -*/ diff --git a/xlators/encryption/crypt/src/metadata.h b/xlators/encryption/crypt/src/metadata.h deleted file mode 100644 index 0bcee1b18c8..00000000000 --- a/xlators/encryption/crypt/src/metadata.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -  Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __METADATA_H__ -#define __METADATA_H__ - -#define NMTD_8_MAC_SIZE (8) -#define EMTD_8_MAC_SIZE (8) - -typedef uint8_t nmtd_8_mac_t[NMTD_8_MAC_SIZE]; -typedef uint8_t emtd_8_mac_t[EMTD_8_MAC_SIZE]; - -/* - * Version "v1" of file's metadata. - * Metadata of this version has 4 components: - * - * 1) EMTD (Encrypted part of MeTaData); - * 2) NMTD (Non-encrypted part of MeTaData); - * 3) EMTD_MAC; (EMTD Message Authentication Code); - * 4) Array of per-link NMTD MACs (for every (hard)link it includes - *    exactly one MAC) - */ -struct mtd_format_v1 { -    /* EMTD, encrypted part of meta-data */ -    uint8_t alg_id;      /* cipher algorithm id (only AES for now) */ -    uint8_t mode_id;     /* cipher mode id; (only XTS for now) */ -    uint8_t block_bits;  /* encoded block size */ -    uint8_t minor_id;    /* client translator id */ -    uint8_t dkey_factor; /* encoded size of the data key */ -    /* MACs */ -    emtd_8_mac_t gmac; /* MAC of the encrypted meta-data, 8 bytes */ -    nmtd_8_mac_t omac; /* per-link MACs of the non-encrypted -                        * meta-data: at least one such MAC is always -                        * present */ -} __attribute__((packed)); - -/* - * NMTD, the non-encrypted part of metadata of version "v1" - * is file's gfid, which is generated on trusted machines. - */ -#define SIZE_OF_NMTD_V1 (sizeof(uuid_t)) -#define SIZE_OF_EMTD_V1                                                        \ -    (offsetof(struct mtd_format_v1, gmac) -                                    \ -     offsetof(struct mtd_format_v1, alg_id)) -#define SIZE_OF_NMTD_V1_MAC (NMTD_8_MAC_SIZE) -#define SIZE_OF_EMTD_V1_MAC (EMTD_8_MAC_SIZE) - -static inline unsigned char * -get_EMTD_V1(struct mtd_format_v1 *format) -{ -    return &format->alg_id; -} - -static inline unsigned char * -get_NMTD_V1(struct crypt_inode_info *info) -{ -    return info->oid; -} - -static inline unsigned char * -get_EMTD_V1_MAC(struct mtd_format_v1 *format) -{ -    return format->gmac; -} - -static inline unsigned char * -get_NMTD_V1_MAC(struct mtd_format_v1 *format) -{ -    return format->omac; -} - -#endif /* __METADATA_H__ */ diff --git a/xlators/encryption/rot-13/Makefile.am b/xlators/encryption/rot-13/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/xlators/encryption/rot-13/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/xlators/experimental/Makefile.am b/xlators/experimental/Makefile.am deleted file mode 100644 index a530845c4c0..00000000000 --- a/xlators/experimental/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = jbr-client jbr-server fdl dht2 posix2 - -CLEANFILES = diff --git a/xlators/experimental/README.md b/xlators/experimental/README.md deleted file mode 100644 index b00f24e114b..00000000000 --- a/xlators/experimental/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# Purpose of this directory - -This directory is created to host experimental gluster translators. A new -translator that is *experimental* in nature, would need to create its own -subdirectory under this directory, to host/publish its work. - -Example: -  The first commit should include the following changes -    1. xlators/experimental/Makefile.am -      NOTE: Add foobar to the list of SUBDIRS here -    2. xlators/experimental/foobar -    3. xlators/experimental/foobar/Makefle.am -      NOTE: Can be empty initially in the first commit -    4. configure.ac -      NOTE: Include your experimental Makefile under AC_CONFIG_FILES -    5. xlators/experimental/foobar/README.md -      NOTE: The readme should cover details as required for the translator to be -      accepted as experimental, primarily including a link to the specification -      under the gluster-specs repository [1]. Later the readme should suffice -      as an entry point for developers and users alike, who wish to experiment -      with the xlator under development -    6. xlators/experimental/foobar/TODO.md -      NOTE: This is a list of TODO's identified during the development process -      that needs addressing over time. These include exceptions granted during -      the review process, for things not addressed when commits are merged into -      the repository - -# Why is it provided - -Quite often translator development that happens out of tree, does not get -enough eyeballs early in its development phase, has not undergone CI -(regression/continuous integration testing), and at times is not well integrated -with the rest of gluster stack. - -Also, when such out of tree translators are submitted for acceptance, it is a -bulk commit that makes review difficult and inefficient. Such submissions also -have to be merged forward, and depending on the time spent in developing the -translator the master branch could have moved far ahead, making this a painful -activity. - -Experimental is born out of such needs, to provide xlator developers, -  - Early access to CI -  - Ability to adapt to ongoing changes in other parts of gluster -  - More eye balls on the code and design aspects of the translator -  - TBD: What else? - -and for maintainers, -  - Ability to look at smaller change sets in the review process -  - Ability to verify/check implementation against the specification provided - -# General rules - -1. If a new translator is added under here it should, at the very least, pass -compilation. - -2. All translators under the experimental directory are shipped as a part of -gluster-experimental RPMs. -TBD: Spec file and other artifacts for the gluster-experimental RPM needs to be -fleshed out. - -3. Experimental translators can leverage the CI framework as needed. Tests need -to be hosted under xlators/experimental/tests initially, and later moved to the -appropriate tests/ directory as the xlator matures. It is encouraged to provide -tests for each commit or series of commits, so that code and tests can be -inspected together. - -4. If any experimental translator breaks CI, it is quarantined till demonstrable -proof towards the contrary is provided. This is applicable as tests are moved -out of experimental tests directory to the CI framework directory, as otherwise -experimental tests are not a part of regular CI regression runs. - -5. An experimental translator need not function at all, as a result commits can -be merged pretty much at will as long as other rules as stated are not violated. - -6. Experimental submissions will be assigned a existing maintainer, to aid -merging commits and ensure aspects of gluster code submissions are respected. -When an experimental xlator is proposed and the first commit posted -a mail to gluster-devel@gluster.org requesting attention, will assign the -maintainer buddy for the submission. -NOTE: As we scale, this may change. - -6. More? - -# Getting out of the experimental jail - -So you now think your xlator is ready to leave experimental and become part of -mainline! -- TBD: guidelines pending. - -# FAQs - -1. How do I submit/commit experimental framework changes outside of my -experimental xlator? -  - Provide such framework changes as a separate commit -  - Conditionally ensure these are built or activated only when the experimental -  feature is activated, so as to prevent normal gluster workflow to function as -  before -  - TBD: guidelines and/or examples pending. - -2. Ask your question either on gluster-devel@gluster.org or as a change request -to this file in gluster gerrit [2] for an answer that will be assimilated into -this readme. - -# Links -[1] http://review.gluster.org/#/q/project:glusterfs-specs - -[2] http://review.gluster.org/#/q/project:glusterfs diff --git a/xlators/experimental/dht2/Makefile.am b/xlators/experimental/dht2/Makefile.am deleted file mode 100644 index 9d910a66056..00000000000 --- a/xlators/experimental/dht2/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = dht2-client dht2-server - -CLEANFILES = diff --git a/xlators/experimental/dht2/README.md b/xlators/experimental/dht2/README.md deleted file mode 100644 index 8f249a83673..00000000000 --- a/xlators/experimental/dht2/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# DHT2 Experimental README - -DHT2 is the new distribution scheme being developed for Gluster, that -aims to remove the subdirectory spread across all DHT subvolumes. - -As a result of this work, the Gluster backend file layouts and on disk -representation of directories and files are modified, thus making DHT2 -volumes incompatible to existing DHT based Gluster deployments. - -This document presents interested users with relevant data to play around -with DHT2 volumes and provide feedback towards the same. - -REMOVEME: Design details currently under review here, -	- http://review.gluster.org/#/c/13395/ - -TODO: Add more information as relevant code is pulled in - -# Directory strucutre elaborated - -## dht2-server -This directory contains code for the server side DHT2 xlator. This xlator is -intended to run on the brick graph, and is responsible for FOP synchronization, -redirection, transactions, and journal replays. - -NOTE: The server side code also handles changes to volume/cluster map and -also any rebalance activities. - -## dht2-client -This directory contains code for the client side DHT2 xlator. This xlator is -intended to run on the client/access protocol/mount graph, and is responsible -for FOP routing to the right DHT2 subvolume. It uses a volume/cluster wide map -of the routing (layout), to achieve the same. - -## dht2-common -This directory contains code that is used in common across other parts of DHT2. -For example, FOP routing store/consult abstractions that are common across the -client and server side of DHT2. - -## Issue: How to build dht2-common? -  1. Build a shared object -    - We cannot ship this as a part of both the client xlator RPM -  2. Build an archive -    - Symbol clashes? when both the client and server xlators are loaded as a -    part of the same graph -  3. Compile with other parts of the code that needs it  -    - Not a very different from (2) above -    - This is what is chosen at present, and maybe would be revised later diff --git a/xlators/experimental/dht2/TODO.md b/xlators/experimental/dht2/TODO.md deleted file mode 100644 index 1e2c53c5b36..00000000000 --- a/xlators/experimental/dht2/TODO.md +++ /dev/null @@ -1,3 +0,0 @@ -# DHT2 TODO list - -<Items will be added as code is pulled into the repository> diff --git a/xlators/experimental/dht2/dht2-client/Makefile.am b/xlators/experimental/dht2/dht2-client/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/dht2/dht2-client/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/dht2/dht2-client/src/Makefile.am b/xlators/experimental/dht2/dht2-client/src/Makefile.am deleted file mode 100644 index 3a13a2a3986..00000000000 --- a/xlators/experimental/dht2/dht2-client/src/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental -xlator_LTLIBRARIES = dht2c.la - -dht2c_sources = dht2-client-main.c - -dht2common_sources = $(top_srcdir)/xlators/experimental/dht2/dht2-common/src/dht2-common-map.c - -dht2c_la_SOURCES = $(dht2c_sources) $(dht2common_sources) -dht2c_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -dht2c_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -AM_CPPFLAGS = $(GF_CPPFLAGS) -AM_CPPFLAGS += -I$(top_srcdir)/xlators/experimental/dht2/dht2-common/src/ -AM_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src -AM_CPPFLAGS += -I$(top_srcdir)/rpc/xdr/src -AM_CPPFLAGS += -I$(top_builddir)/rpc/xdr/src -AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src - -CLEANFILES = diff --git a/xlators/experimental/dht2/dht2-client/src/dht2-client-main.c b/xlators/experimental/dht2/dht2-client/src/dht2-client-main.c deleted file mode 100644 index 14a4c0e04fe..00000000000 --- a/xlators/experimental/dht2/dht2-client/src/dht2-client-main.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -/* File: dht2-client-main.c - * This file contains the xlator loading functions, FOP entry points - * and options. - * The entire functionality including comments is TODO. - */ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/statedump.h> - -int32_t -dht2_client_init(xlator_t *this) -{ -    if (!this->children) { -        gf_log(this->name, GF_LOG_ERROR, -               "Missing children in volume graph, this (%s) is" -               " not a leaf translator", -               this->name); -        return -1; -    } - -    return 0; -} - -void -dht2_client_fini(xlator_t *this) -{ -    return; -} - -class_methods_t class_methods = { -    .init = dht2_client_init, -    .fini = dht2_client_fini, -}; - -struct xlator_fops fops = {}; - -struct xlator_cbks cbks = {}; - -/* -struct xlator_dumpops dumpops = { -}; -*/ - -struct volume_options options[] = { -    {.key = {NULL}}, -}; diff --git a/xlators/experimental/dht2/dht2-common/src/dht2-common-map.c b/xlators/experimental/dht2/dht2-common/src/dht2-common-map.c deleted file mode 100644 index 84ff27241d3..00000000000 --- a/xlators/experimental/dht2/dht2-common/src/dht2-common-map.c +++ /dev/null @@ -1,19 +0,0 @@ -/* -  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -/* File: dht2-common-map.c - * This file contains helper routines to store, consult, the volume map - * for subvolume to GFID relations. - * The entire functionality including comments is TODO. - */ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/logging.h> -#include <glusterfs/statedump.h> diff --git a/xlators/experimental/dht2/dht2-server/Makefile.am b/xlators/experimental/dht2/dht2-server/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/dht2/dht2-server/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/dht2/dht2-server/src/Makefile.am b/xlators/experimental/dht2/dht2-server/src/Makefile.am deleted file mode 100644 index c76fab0ca74..00000000000 --- a/xlators/experimental/dht2/dht2-server/src/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -if WITH_SERVER -xlator_LTLIBRARIES = dht2s.la -endif -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental - -dht2s_sources = dht2-server-main.c - -dht2common_sources = $(top_srcdir)/xlators/experimental/dht2/dht2-common/src/dht2-common-map.c - -dht2s_la_SOURCES = $(dht2s_sources) $(dht2common_sources) -dht2s_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -dht2s_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -AM_CPPFLAGS = $(GF_CPPFLAGS) -AM_CPPFLAGS += -I$(top_srcdir)/xlators/experimental/dht2/dht2-common/src/ -AM_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src -AM_CPPFLAGS += -I$(top_srcdir)/rpc/xdr/src -AM_CPPFLAGS += -I$(top_builddir)/rpc/xdr/src -AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src - -CLEANFILES = diff --git a/xlators/experimental/dht2/dht2-server/src/dht2-server-main.c b/xlators/experimental/dht2/dht2-server/src/dht2-server-main.c deleted file mode 100644 index 6f67e07ffdf..00000000000 --- a/xlators/experimental/dht2/dht2-server/src/dht2-server-main.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -/* File: dht2-server-main.c - * This file contains the xlator loading functions, FOP entry points - * and options. - * The entire functionality including comments is TODO. - */ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/statedump.h> - -int32_t -dht2_server_init(xlator_t *this) -{ -    if (!this->children) { -        gf_log(this->name, GF_LOG_ERROR, -               "Missing children in volume graph, this (%s) is" -               " not a leaf translator", -               this->name); -        return -1; -    } - -    return 0; -} - -void -dht2_server_fini(xlator_t *this) -{ -    return; -} - -class_methods_t class_methods = { -    .init = dht2_server_init, -    .fini = dht2_server_fini, -}; - -struct xlator_fops fops = {}; - -struct xlator_cbks cbks = {}; - -/* -struct xlator_dumpops dumpops = { -}; -*/ - -struct volume_options options[] = { -    {.key = {NULL}}, -}; diff --git a/xlators/experimental/fdl/Makefile.am b/xlators/experimental/fdl/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/fdl/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/fdl/src/Makefile.am b/xlators/experimental/fdl/src/Makefile.am deleted file mode 100644 index bdcaaf6c38d..00000000000 --- a/xlators/experimental/fdl/src/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental -if WITH_SERVER -xlator_LTLIBRARIES = fdl.la -endif - -noinst_HEADERS = fdl.h - -nodist_fdl_la_SOURCES = fdl.c -fdl_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -fdl_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -if WITH_SERVER -sbin_PROGRAMS = gf_logdump gf_recon -endif -gf_logdump_SOURCES = logdump.c -nodist_gf_logdump_SOURCES = libfdl.c -gf_logdump_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ -	$(top_builddir)/api/src/libgfapi.la $(GFAPI_LIBS) $(UUID_LIBS) - -# Eventually recon(ciliation) code will move elsewhere, but for now it's -# easier to have it next to the similar logdump code. -gf_recon_SOURCES = recon.c -nodist_gf_recon_SOURCES = librecon.c -gf_recon_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ -	$(top_builddir)/api/src/libgfapi.la $(GFAPI_LIBS) $(UUID_LIBS) - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -	-I$(top_srcdir)/api/src -fPIC \ -	-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) \ -	-DDATADIR=\"$(localstatedir)\" - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -noinst_PYTHON = gen_fdl.py gen_dumper.py gen_recon.py -EXTRA_DIST = fdl-tmpl.c.in dump-tmpl.c.in recon-tmpl.c.in - -CLEANFILES = $(nodist_fdl_la_SOURCES) $(nodist_gf_logdump_SOURCES) \ -	$(nodist_gf_recon_SOURCES) - -fdl.c: fdl-tmpl.c.in gen_fdl.py -	$(PYTHON) $(srcdir)/gen_fdl.py $(srcdir)/fdl-tmpl.c.in > $@ - -libfdl.c: dump-tmpl.c.in gen_dumper.py -	$(PYTHON) $(srcdir)/gen_dumper.py $(srcdir)/dump-tmpl.c.in > $@ - -librecon.c: recon-tmpl.c.in gen_recon.py -	$(PYTHON) $(srcdir)/gen_recon.py $(srcdir)/recon-tmpl.c.in > $@ diff --git a/xlators/experimental/fdl/src/dump-tmpl.c.in b/xlators/experimental/fdl/src/dump-tmpl.c.in deleted file mode 100644 index 97249ac3e71..00000000000 --- a/xlators/experimental/fdl/src/dump-tmpl.c.in +++ /dev/null @@ -1,177 +0,0 @@ -#pragma fragment PROLOG -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#include <ctype.h> -#endif - -#include "glfs.h" -#include "iatt.h" -#include "xlator.h" -#include "fdl.h" - -/* - * Returns 0 if the string is ASCII printable * - * and -1 if it's not ASCII printable         * - */ -int -str_isprint(char *s) -{ -    int ret = -1; - -    if (!s) -        goto out; - -    while (s[0] != '\0') { -        if (!isprint(s[0])) -            goto out; -        else -            s++; -    } - -    ret = 0; -out: -    return ret; -} - -#pragma fragment DICT -{ -    int key_len, data_len; -    char *key_ptr; -    char *key_val; -    printf("@ARGNAME@ = dict {\n"); -    for (;;) { -        key_len = *((int *)new_meta); -        new_meta += sizeof(int); -        if (!key_len) { -            break; -        } -        key_ptr = new_meta; -        new_meta += key_len; -        data_len = *((int *)new_meta); -        key_val = new_meta + sizeof(int); -        new_meta += sizeof(int) + data_len; -        if (str_isprint(key_val)) -            printf(" %s = <%d bytes>\n", key_ptr, data_len); -        else -            printf(" %s = %s <%d bytes>\n", key_ptr, key_val, data_len); -    } -    printf("}\n"); -} - -#pragma fragment DOUBLE -printf("@ARGNAME@ = @FORMAT@\n", *((uint64_t *)new_meta), -       *((uint64_t *)new_meta)); -new_meta += sizeof(uint64_t); - -#pragma fragment GFID -printf("@ARGNAME@ = <gfid %s>\n", uuid_utoa(*((uuid_t *)new_meta))); -new_meta += 16; - -#pragma fragment INTEGER -printf("@ARGNAME@ = @FORMAT@\n", *((uint32_t *)new_meta), -       *((uint32_t *)new_meta)); -new_meta += sizeof(uint32_t); - -#pragma fragment LOC -printf("@ARGNAME@ = loc {\n"); -printf("  gfid = %s\n", uuid_utoa(*((uuid_t *)new_meta))); -new_meta += 16; -printf("  pargfid = %s\n", uuid_utoa(*((uuid_t *)new_meta))); -new_meta += 16; -if (*(new_meta++)) { -    printf("  name = %s\n", new_meta); -    new_meta += (strlen(new_meta) + 1); -} -printf("}\n"); - -#pragma fragment STRING -if (*(new_meta++)) { -    printf("@ARGNAME@ = %s\n", new_meta); -    new_meta += (strlen(new_meta) + 1); -} - -#pragma fragment VECTOR -{ -    size_t len = *((size_t *)new_meta); -    new_meta += sizeof(len); -    printf("@ARGNAME@ = <%zu bytes>\n", len); -    new_data += len; -} - -#pragma fragment IATT -{ -    ia_prot_t *myprot = ((ia_prot_t *)new_meta); -    printf("@ARGNAME@ = iatt {\n"); -    printf("  ia_prot = %c%c%c", myprot->suid ? 'S' : '-', -           myprot->sgid ? 'S' : '-', myprot->sticky ? 'T' : '-'); -    printf("%c%c%c", myprot->owner.read ? 'r' : '-', -           myprot->owner.write ? 'w' : '-', myprot->owner.exec ? 'x' : '-'); -    printf("%c%c%c", myprot->group.read ? 'r' : '-', -           myprot->group.write ? 'w' : '-', myprot->group.exec ? 'x' : '-'); -    printf("%c%c%c\n", myprot->other.read ? 'r' : '-', -           myprot->other.write ? 'w' : '-', myprot->other.exec ? 'x' : '-'); -    new_meta += sizeof(ia_prot_t); -    uint32_t *myints = (uint32_t *)new_meta; -    printf("  ia_uid = %u\n", myints[0]); -    printf("  ia_gid = %u\n", myints[1]); -    printf("  ia_atime = %u.%09u\n", myints[2], myints[3]); -    printf("  ia_mtime = %u.%09u\n", myints[4], myints[5]); -    new_meta += sizeof(*myints) * 6; -} - -#pragma fragment FOP -void fdl_dump_@NAME@(char **old_meta, char **old_data) -{ -    char *new_meta = *old_meta; -    char *new_data = *old_data; - -    /* TBD: word size/endianness */ -    @FUNCTION_BODY@ - -    *old_meta = new_meta; -    *old_data = new_data; -} - -#pragma fragment CASE -case GF_FOP_@UPNAME@: -    printf("=== GF_FOP_@UPNAME@\n"); -    fdl_dump_@NAME@(&new_meta, &new_data); -    break; - -#pragma fragment EPILOG -    int -    fdl_dump(char **old_meta, char **old_data) -    { -        char *new_meta = *old_meta; -        char *new_data = *old_data; -        static glfs_t *fs = NULL; -        int recognized = 1; -        event_header_t *eh; - -        /* -         * We don't really call anything else in GFAPI, but this is the most -         * convenient way to satisfy all of the spurious dependencies on how it -         * or glusterfsd initialize (e.g. setting up THIS). -         */ -        if (!fs) { -            fs = glfs_new("dummy"); -        } - -        eh = (event_header_t *)new_meta; -        new_meta += sizeof(*eh); - -        /* TBD: check event_type instead of assuming NEW_REQUEST */ - -        switch (eh->fop_type) { -            @SWITCH_BODY@ - -            default : -                printf("unknown fop %u\n", eh->fop_type); -                recognized = 0; -        } - -        *old_meta = new_meta; -        *old_data = new_data; -        return recognized; -    } diff --git a/xlators/experimental/fdl/src/fdl-tmpl.c.in b/xlators/experimental/fdl/src/fdl-tmpl.c.in deleted file mode 100644 index c99157be957..00000000000 --- a/xlators/experimental/fdl/src/fdl-tmpl.c.in +++ /dev/null @@ -1,513 +0,0 @@ -/* -  Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <fcntl.h> -#include <unistd.h> -#include <sys/mman.h> -#include "call-stub.h" -#include "iatt.h" -#include "defaults.h" -#include "syscall.h" -#include "xlator.h" -#include "fdl.h" - -/* TBD: make tunable */ -#define META_FILE_SIZE (1 << 20) -#define DATA_FILE_SIZE (1 << 24) - -enum gf_fdl { gf_fdl_mt_fdl_private_t = gf_common_mt_end + 1, gf_fdl_mt_end }; - -typedef struct { -    char *type; -    off_t size; -    char *path; -    int fd; -    void *ptr; -    off_t max_offset; -} log_obj_t; - -typedef struct { -    struct list_head reqs; -    pthread_mutex_t req_lock; -    pthread_cond_t req_cond; -    char *log_dir; -    pthread_t worker; -    gf_boolean_t should_stop; -    gf_boolean_t change_term; -    log_obj_t meta_log; -    log_obj_t data_log; -    int term; -    int first_term; -} fdl_private_t; - -int32_t -fdl_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata); - -void -fdl_enqueue(xlator_t *this, call_stub_t *stub) -{ -    fdl_private_t *priv = this->private; - -    pthread_mutex_lock(&priv->req_lock); -    list_add_tail(&stub->list, &priv->reqs); -    pthread_mutex_unlock(&priv->req_lock); - -    pthread_cond_signal(&priv->req_cond); -} - -#pragma generate - -char * -fdl_open_term_log(xlator_t *this, log_obj_t *obj, int term) -{ -    fdl_private_t *priv = this->private; -    int ret; -    char *ptr = NULL; - -    /* -     * Use .jnl instead of .log so that we don't get test info (mistakenly) -     * appended to our journal files. -     */ -    if (this->ctx->cmd_args.log_ident) { -        ret = gf_asprintf(&obj->path, "%s/%s-%s-%d.jnl", priv->log_dir, -                          this->ctx->cmd_args.log_ident, obj->type, term); -    } else { -        ret = gf_asprintf(&obj->path, "%s/fubar-%s-%d.jnl", priv->log_dir, -                          obj->type, term); -    } -    if ((ret <= 0) || !obj->path) { -        gf_log(this->name, GF_LOG_ERROR, "failed to construct log-file path"); -        goto err; -    } - -    gf_log(this->name, GF_LOG_INFO, "opening %s (size %" PRId64 ")", obj->path, -           obj->size); - -    obj->fd = open(obj->path, O_RDWR | O_CREAT | O_TRUNC, 0666); -    if (obj->fd < 0) { -        gf_log(this->name, GF_LOG_ERROR, "failed to open log file (%s)", -               strerror(errno)); -        goto err; -    } - -#if !defined(GF_BSD_HOST_OS) -    /* -     * NetBSD can just go die in a fire.  Even though it claims to support -     * fallocate/posix_fallocate they don't actually *do* anything so the -     * file size remains zero.  Then mmap succeeds anyway, but any access -     * to the mmap'ed region will segfault.  It would be acceptable for -     * fallocate to do what it says, for mmap to fail, or for access to -     * extend the file.  NetBSD managed to hit the trifecta of Getting -     * Everything Wrong, and debugging in that environment to get this far -     * has already been painful enough (systems I worked on in 1990 were -     * better that way).  We'll fall through to the lseek/write method, and -     * performance will be worse, and TOO BAD. -     */ -    if (sys_fallocate(obj->fd, 0, 0, obj->size) < 0) -#endif -    { -        gf_log(this->name, GF_LOG_WARNING, -               "failed to fallocate space for log file"); -        /* Have to do this the ugly page-faulty way. */ -        (void)sys_lseek(obj->fd, obj->size - 1, SEEK_SET); -        (void)sys_write(obj->fd, "", 1); -    } - -    ptr = mmap(NULL, obj->size, PROT_WRITE, MAP_SHARED, obj->fd, 0); -    if (ptr == MAP_FAILED) { -        gf_log(this->name, GF_LOG_ERROR, "failed to mmap log (%s)", -               strerror(errno)); -        goto err; -    } - -    obj->ptr = ptr; -    obj->max_offset = 0; -    return ptr; - -err: -    if (obj->fd >= 0) { -        sys_close(obj->fd); -        obj->fd = (-1); -    } -    if (obj->path) { -        GF_FREE(obj->path); -        obj->path = NULL; -    } -    return ptr; -} - -void -fdl_close_term_log(xlator_t *this, log_obj_t *obj) -{ -    fdl_private_t *priv = this->private; - -    if (obj->ptr) { -        (void)munmap(obj->ptr, obj->size); -        obj->ptr = NULL; -    } - -    if (obj->fd >= 0) { -        gf_log(this->name, GF_LOG_INFO, -               "truncating term %d %s journal to %" PRId64, -               priv->term, obj->type, obj->max_offset); -        if (sys_ftruncate(obj->fd, obj->max_offset) < 0) { -            gf_log(this->name, GF_LOG_WARNING, -                   "failed to truncate journal (%s)", strerror(errno)); -        } -        sys_close(obj->fd); -        obj->fd = (-1); -    } - -    if (obj->path) { -        GF_FREE(obj->path); -        obj->path = NULL; -    } -} - -gf_boolean_t -fdl_change_term(xlator_t *this, char **meta_ptr, char **data_ptr) -{ -    fdl_private_t *priv = this->private; - -    fdl_close_term_log(this, &priv->meta_log); -    fdl_close_term_log(this, &priv->data_log); - -    ++(priv->term); - -    *meta_ptr = fdl_open_term_log(this, &priv->meta_log, priv->term); -    if (!*meta_ptr) { -        return _gf_false; -    } - -    *data_ptr = fdl_open_term_log(this, &priv->data_log, priv->term); -    if (!*data_ptr) { -        return _gf_false; -    } - -    return _gf_true; -} - -void * -fdl_worker(void *arg) -{ -    xlator_t *this = arg; -    fdl_private_t *priv = this->private; -    call_stub_t *stub; -    char *meta_ptr = NULL; -    off_t *meta_offset = &priv->meta_log.max_offset; -    char *data_ptr = NULL; -    off_t *data_offset = &priv->data_log.max_offset; -    unsigned long base_as_ul; -    void *msync_ptr; -    size_t msync_len; -    gf_boolean_t recycle; -    void *err_label = &&err_unlocked; - -    priv->meta_log.type = "meta"; -    priv->meta_log.size = META_FILE_SIZE; -    priv->meta_log.path = NULL; -    priv->meta_log.fd = (-1); -    priv->meta_log.ptr = NULL; - -    priv->data_log.type = "data"; -    priv->data_log.size = DATA_FILE_SIZE; -    priv->data_log.path = NULL; -    priv->data_log.fd = (-1); -    priv->data_log.ptr = NULL; - -    /* TBD: initial term should come from persistent storage (e.g. etcd) */ -    priv->first_term = ++(priv->term); -    meta_ptr = fdl_open_term_log(this, &priv->meta_log, priv->term); -    if (!meta_ptr) { -        goto *err_label; -    } -    data_ptr = fdl_open_term_log(this, &priv->data_log, priv->term); -    if (!data_ptr) { -        fdl_close_term_log(this, &priv->meta_log); -        goto *err_label; -    } - -    for (;;) { -        pthread_mutex_lock(&priv->req_lock); -        err_label = &&err_locked; -        while (list_empty(&priv->reqs)) { -            pthread_cond_wait(&priv->req_cond, &priv->req_lock); -            if (priv->should_stop) { -                goto *err_label; -            } -            if (priv->change_term) { -                if (!fdl_change_term(this, &meta_ptr, &data_ptr)) { -                    goto *err_label; -                } -                priv->change_term = _gf_false; -                continue; -            } -        } -        stub = list_entry(priv->reqs.next, call_stub_t, list); -        list_del_init(&stub->list); -        pthread_mutex_unlock(&priv->req_lock); -        err_label = &&err_unlocked; -        /* -         * TBD: batch requests -         * -         * What we should do here is gather up *all* of the requests -         * that have accumulated since we were last at this point, -         * blast them all out in one big writev, and then dispatch them -         * all before coming back for more.  That maximizes throughput, -         * at some cost to latency (due to queuing effects at the log -         * stage).  Note that we're likely to be above io-threads, so -         * the dispatch itself will be parallelized (at further cost to -         * latency).  For now, we just do the simplest thing and handle -         * one request all the way through before fetching the next. -         * -         * So, why mmap/msync instead of writev/fdatasync?  Because it's -         * faster.  Much faster.  So much faster that I half-suspect -         * cheating, but it's more convenient for now than having to -         * ensure that everything's page-aligned for O_DIRECT (the only -         * alternative that still might avoid ridiculous levels of -         * local-FS overhead). -         * -         * TBD: check that msync really does get our data to disk. -         */ -        gf_log(this->name, GF_LOG_DEBUG, "logging %u+%u bytes for op %d", -               stub->jnl_meta_len, stub->jnl_data_len, stub->fop); -        recycle = _gf_false; -        if ((*meta_offset + stub->jnl_meta_len) > priv->meta_log.size) { -            recycle = _gf_true; -        } -        if ((*data_offset + stub->jnl_data_len) > priv->data_log.size) { -            recycle = _gf_true; -        } -        if (recycle && !fdl_change_term(this, &meta_ptr, &data_ptr)) { -            goto *err_label; -        } -        meta_ptr = priv->meta_log.ptr; -        data_ptr = priv->data_log.ptr; -        gf_log(this->name, GF_LOG_DEBUG, "serializing to %p/%p", -               meta_ptr + *meta_offset, data_ptr + *data_offset); -        stub->serialize(stub, meta_ptr + *meta_offset, data_ptr + *data_offset); -        if (stub->jnl_meta_len > 0) { -            base_as_ul = (unsigned long)(meta_ptr + *meta_offset); -            msync_ptr = (void *)(base_as_ul & ~0x0fff); -            msync_len = (size_t)(base_as_ul & 0x0fff); -            if (msync(msync_ptr, msync_len + stub->jnl_meta_len, MS_SYNC) < 0) { -                gf_log(this->name, GF_LOG_WARNING, -                       "failed to log request meta (%s)", strerror(errno)); -            } -            *meta_offset += stub->jnl_meta_len; -        } -        if (stub->jnl_data_len > 0) { -            base_as_ul = (unsigned long)(data_ptr + *data_offset); -            msync_ptr = (void *)(base_as_ul & ~0x0fff); -            msync_len = (size_t)(base_as_ul & 0x0fff); -            if (msync(msync_ptr, msync_len + stub->jnl_data_len, MS_SYNC) < 0) { -                gf_log(this->name, GF_LOG_WARNING, -                       "failed to log request data (%s)", strerror(errno)); -            } -            *data_offset += stub->jnl_data_len; -        } -        call_resume(stub); -    } - -err_locked: -    pthread_mutex_unlock(&priv->req_lock); -err_unlocked: -    fdl_close_term_log(this, &priv->meta_log); -    fdl_close_term_log(this, &priv->data_log); -    return NULL; -} - -int32_t -fdl_ipc_continue(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) -{ -    /* -     * Nothing to be done here. Just Unwind. * -     */ -    STACK_UNWIND_STRICT(ipc, frame, 0, 0, xdata); - -    return 0; -} - -int32_t -fdl_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) -{ -    call_stub_t *stub; -    fdl_private_t *priv = this->private; -    dict_t *tdict; -    int32_t gt_err = EIO; - -    switch (op) { -        case FDL_IPC_CHANGE_TERM: -            gf_log(this->name, GF_LOG_INFO, "got CHANGE_TERM op"); -            priv->change_term = _gf_true; -            pthread_cond_signal(&priv->req_cond); -            STACK_UNWIND_STRICT(ipc, frame, 0, 0, NULL); -            break; - -        case FDL_IPC_GET_TERMS: -            gf_log(this->name, GF_LOG_INFO, "got GET_TERMS op"); -            tdict = dict_new(); -            if (!tdict) { -                gt_err = ENOMEM; -                goto gt_done; -            } -            if (dict_set_int32(tdict, "first", priv->first_term) != 0) { -                goto gt_done; -            } -            if (dict_set_int32(tdict, "last", priv->term) != 0) { -                goto gt_done; -            } -            gt_err = 0; -        gt_done: -            if (gt_err) { -                STACK_UNWIND_STRICT(ipc, frame, -1, gt_err, NULL); -            } else { -                STACK_UNWIND_STRICT(ipc, frame, 0, 0, tdict); -            } -            if (tdict) { -                dict_unref(tdict); -            } -            break; - -        case FDL_IPC_JBR_SERVER_ROLLBACK: -            /* -             * In case of a rollback from jbr-server, dump  * -             * the term and index number in the journal,    * -             * which will later be used to rollback the fop * -             */ -            stub = fop_ipc_stub(frame, fdl_ipc_continue, op, xdata); -            fdl_len_ipc(stub); -            stub->serialize = fdl_serialize_ipc; -            fdl_enqueue(this, stub); - -            break; - -        default: -            STACK_WIND_TAIL(frame, FIRST_CHILD(this), -                            FIRST_CHILD(this)->fops->ipc, op, xdata); -    } - -    return 0; -} - -int -fdl_init(xlator_t *this) -{ -    fdl_private_t *priv = NULL; - -    priv = GF_CALLOC(1, sizeof(*priv), gf_fdl_mt_fdl_private_t); -    if (!priv) { -        gf_log(this->name, GF_LOG_ERROR, "failed to allocate fdl_private"); -        goto err; -    } - -    INIT_LIST_HEAD(&priv->reqs); -    if (pthread_mutex_init(&priv->req_lock, NULL) != 0) { -        gf_log(this->name, GF_LOG_ERROR, "failed to initialize req_lock"); -        goto err; -    } -    if (pthread_cond_init(&priv->req_cond, NULL) != 0) { -        gf_log(this->name, GF_LOG_ERROR, "failed to initialize req_cond"); -        goto err; -    } - -    GF_OPTION_INIT("log-path", priv->log_dir, path, err); - -    this->private = priv; -    /* -     * The rest of the fop table is automatically generated, so this is a -     * bit cleaner than messing with the generation to add a hand-written -     * exception. -     */ - -    if (gf_thread_create(&priv->worker, NULL, fdl_worker, this, "fdlwrker") != -        0) { -        gf_log(this->name, GF_LOG_ERROR, "failed to start fdl_worker"); -        goto err; -    } - -    return 0; - -err: -    if (priv) { -        GF_FREE(priv); -    } -    return -1; -} - -void -fdl_fini(xlator_t *this) -{ -    fdl_private_t *priv = this->private; - -    if (priv) { -        priv->should_stop = _gf_true; -        pthread_cond_signal(&priv->req_cond); -        pthread_join(priv->worker, NULL); -        GF_FREE(priv); -    } -} - -int -fdl_reconfigure(xlator_t *this, dict_t *options) -{ -    fdl_private_t *priv = this->private; - -    GF_OPTION_RECONF("log_dir", priv->log_dir, options, path, out); -    /* TBD: react if it changed */ - -out: -    return 0; -} - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    GF_VALIDATE_OR_GOTO("fdl", this, out); - -    ret = xlator_mem_acct_init(this, gf_fdl_mt_end + 1); - -    if (ret != 0) { -        gf_log(this->name, GF_LOG_ERROR, -               "Memory accounting init" -               "failed"); -        return ret; -    } -out: -    return ret; -} - -class_methods_t class_methods = { -    .init = fdl_init, -    .fini = fdl_fini, -    .reconfigure = fdl_reconfigure, -    .notify = default_notify, -}; - -struct volume_options options[] = { -    {.key = {"log-path"}, -     .type = GF_OPTION_TYPE_PATH, -     .default_value = DEFAULT_LOG_FILE_DIRECTORY, -     .description = "Directory for FDL files."}, -    {.key = {NULL}}, -}; - -struct xlator_cbks cbks = { -    .release = default_release, -    .releasedir = default_releasedir, -    .forget = default_forget, -}; diff --git a/xlators/experimental/fdl/src/fdl.h b/xlators/experimental/fdl/src/fdl.h deleted file mode 100644 index 827db9f1246..00000000000 --- a/xlators/experimental/fdl/src/fdl.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -   Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#ifndef _FDL_H_ -#define _FDL_H_ - -#define NEW_REQUEST (uint8_t)'N' - -typedef struct { -    uint8_t event_type; /* e.g. NEW_REQUEST */ -    uint8_t fop_type;   /* e.g. GF_FOP_SETATTR */ -    uint16_t request_id; -    uint32_t ext_length; -} event_header_t; - -enum { -    FDL_IPC_BASE = 0xfeedbee5, /* ... and they make honey */ -    FDL_IPC_CHANGE_TERM, -    FDL_IPC_GET_TERMS, -    FDL_IPC_JBR_SERVER_ROLLBACK -}; - -#endif /* _FDL_H_ */ diff --git a/xlators/experimental/fdl/src/gen_dumper.py b/xlators/experimental/fdl/src/gen_dumper.py deleted file mode 100755 index 630b54492f7..00000000000 --- a/xlators/experimental/fdl/src/gen_dumper.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/python3 - -from __future__ import print_function -import os -import re -import sys - -curdir = os.path.dirname (sys.argv[0]) -gendir = os.path.join (curdir, '../../../../libglusterfs/src') -sys.path.append (gendir) -from generator import ops, fop_subs, cbk_subs, generate - -# See the big header comment at the start of gen_fdl.py to see how the stages -# fit together.  The big difference here is that *all* of the C code is in the -# template file as labelled fragments, instead of as Python strings.  That -# makes it much easier to edit in one place, with proper syntax highlighting -# and indentation. -# -#   Stage 1 uses type-specific fragments to generate FUNCTION_BODY, instead of -#   LEN_*_TEMPLATE and SERLZ_*_TEMPLATE to generate LEN_CODE and SER_CODE. -# -#   Stage 2 uses the FOP and CASE fragments instead of RECON_TEMPLATE and -#   FOP_TEMPLATE.  The expanded FOP code (including FUNCTION_BODY substitution -#   in the middle of each function) is emitted immediately; the expanded CASE -#   code is saved for the next stage. -# -#   Stage 3 uses the PROLOG and EPILOG fragments, with the expanded CASE code -#   in the middle of EPILOG, to generate the whole output file. -# -# Another way of looking at it is to consider how the fragments appear in -# the final output: -# -#   PROLOG -#   FOP (expanded for CREATE) -#       FOP before FUNCTION_BODY -#       LOC, INTEGER, GFID, etc. (one per arg, by type) -#       FOP after FUNCTION_BODY -#   FOP (expanded for WRITEV) -#       FOP before FUNCTION_BODY -#       GFID, VECTOR, etc. (on per arg, by type) -#       FOP after FUNCTION_BODY -#   (more FOPs) -#   EPILOG -#       EPILOG before CASE -#       CASE statements (one per fop) -#       EPILOG after CASE - -typemap = { -	'dict_t *':				( "DICT",		""), -	'fd_t *':				( "GFID",		""), -	'dev_t':				( "DOUBLE",		"%\"PRId64\" (0x%\"PRIx64\")"), -	'gf_xattrop_flags_t':	( "INTEGER",	"%d (0x%x)"), -	'int32_t':				( "INTEGER",	"%d (0x%x)"), -	'mode_t':				( "INTEGER",	"%d (0x%x)"), -	'off_t':				( "DOUBLE",		"%\"PRId64\" (0x%\"PRIx64\")"), -	'size_t':				( "DOUBLE",		"%\"PRId64\" (0x%\"PRIx64\")"), -	'uint32_t':				( "INTEGER",	"%d (0x%x)"), -	'loc_t *':				( "LOC",		""), -	'const char *':			( "STRING",		""), -	'struct iovec *':		( "VECTOR",		""), -	'struct iatt *':		( "IATT",		""), -} - -def get_special_subs (args): -	code = "" -	for arg in args: -		if (arg[0] != 'fop-arg') or (len(arg) < 4): -			continue -		recon_type, recon_fmt = typemap[arg[2]] -		code += fragments[recon_type].replace("@ARGNAME@", arg[3])		\ -									 .replace("@FORMAT@", recon_fmt) -	return code - -def gen_functions (): -	code = "" -	for name, value in ops.items(): -		if "journal" not in [ x[0] for x in value ]: -			continue -		fop_subs[name]["@FUNCTION_BODY@"] = get_special_subs(value) -		# Print the FOP fragment with @FUNCTION_BODY@ in the middle. -		code += generate(fragments["FOP"], name, fop_subs) -	return code - -def gen_cases (): -	code = "" -	for name, value in ops.items(): -		if "journal" not in [ x[0] for x in value ]: -			continue -		# Add the CASE fragment for this fop. -		code += generate(fragments["CASE"], name, fop_subs) -	return code - -def load_fragments (path="recon-tmpl.c"): -	pragma_re = re.compile('pragma fragment (.*)') -	cur_symbol = None -	cur_value = "" -	result = {} -	for line in open(path, "r").readlines(): -		m = pragma_re.search(line) -		if m: -			if cur_symbol: -				result[cur_symbol] = cur_value -			cur_symbol = m.group(1) -			cur_value = "" -		else: -			cur_value += line -	if cur_symbol: -		result[cur_symbol] = cur_value -	return result - -if __name__ == "__main__": -	fragments = load_fragments(sys.argv[1]) -	print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") -	print(fragments["PROLOG"]) -	print(gen_functions()) -	print(fragments["EPILOG"].replace("@SWITCH_BODY@", gen_cases())) -	print("/* END GENERATED CODE */") diff --git a/xlators/experimental/fdl/src/gen_fdl.py b/xlators/experimental/fdl/src/gen_fdl.py deleted file mode 100755 index 467ec8927b7..00000000000 --- a/xlators/experimental/fdl/src/gen_fdl.py +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/python3 - -from __future__ import print_function -import os -import sys - -curdir = os.path.dirname (sys.argv[0]) -gendir = os.path.join (curdir, '../../../../libglusterfs/src') -sys.path.append (gendir) -from generator import ops, fop_subs, cbk_subs, generate - -# Generation occurs in three stages.  In this case, it actually makes more -# sense to discuss them in the *opposite* order of that in which they -# actually happen. -# -#   Stage 3 is to insert all of the generated code into a file, replacing the -#   "#pragma generate" that's already there.  The file can thus contain all -#   sorts of stuff that's not specific to one fop, either before or after the -#   generated code as appropriate. -# -#   Stage 2 is to generate all of the code *for a particular fop*, using a -#   string-valued template plus a table of substitution values.  Most of these -#   are built in to the generator itself.  However, we also add a couple that -#   are specific to this particular translator - LEN_CODE and SER_CODE.  These -#   are per-fop functions to get the length or the contents (respectively) of -#   what we'll put in the log.  As with stage 3 allowing per-file boilerplate -#   before and after generated code, this allows per-fop boilerplate before and -#   after generated code. -# -#   Stage 1, therefore, is to create the LEN_CODE and SER_CODE substitutions for -#   each fop, and put them in the same table where e.g. NAME and SHORT_ARGS -#   already are.  We do this by looking at the fop-description table in the -#   generator module, then doing out own template substitution to plug each -#   specific argument name into another string-valued template. -# -# So, what does this leave us with in terms of variables and files? -# -#   For stage 1, we have a series of LEN_*_TEMPLATE and SERLZ_*_TEMPLATE -#   strings, which are used to generate the length and serialization code for -#   each argument type. -# -#   For stage 2, we have a bunch of *_TEMPLATE strings (no LEN_ or SERLZ_ -#   prefix), which are used (along with the output from stage 1) to generate -#   whole functions. -# -#   For stage 3, we have a whole separate file (fdl_tmpl.c) into which we insert -#   the collection of all functions defined in stage 2. - - -LEN_TEMPLATE = """ -void -fdl_len_@NAME@ (call_stub_t *stub) -{ -        uint32_t    meta_len    = sizeof (event_header_t); -		uint32_t	data_len	= 0; - -        /* TBD: global stuff, e.g. uid/gid */ -@LEN_CODE@ - -		/* TBD: pad extension length */ -		stub->jnl_meta_len = meta_len; -		stub->jnl_data_len = data_len; -} -""" - -SER_TEMPLATE = """ -void -fdl_serialize_@NAME@ (call_stub_t *stub, char *meta_buf, char *data_buf) -{ -		event_header_t	*eh; -		unsigned long	offset = 0; - -        /* TBD: word size/endianness */ -		eh = (event_header_t *)meta_buf; -		eh->event_type = NEW_REQUEST; -		eh->fop_type = GF_FOP_@UPNAME@; -		eh->request_id = 0;	// TBD -		meta_buf += sizeof (*eh); -@SER_CODE@ -		/* TBD: pad extension length */ -		eh->ext_length = offset; -} -""" - -CBK_TEMPLATE = """ -int32_t -fdl_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, -                @LONG_ARGS@) -{ -        STACK_UNWIND_STRICT (@NAME@, frame, op_ret, op_errno, -                             @SHORT_ARGS@); -        return 0; -} -""" - -CONTINUE_TEMPLATE = """ -int32_t -fdl_@NAME@_continue (call_frame_t *frame, xlator_t *this, -                     @LONG_ARGS@) -{ -        STACK_WIND (frame, fdl_@NAME@_cbk, -                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, -                    @SHORT_ARGS@); -        return 0; -} - -""" - -FOP_TEMPLATE = """ -int32_t -fdl_@NAME@ (call_frame_t *frame, xlator_t *this, -            @LONG_ARGS@) -{ -        call_stub_t     *stub; - -        stub = fop_@NAME@_stub (frame, default_@NAME@, -                                @SHORT_ARGS@); -		fdl_len_@NAME@ (stub); -        stub->serialize = fdl_serialize_@NAME@; -        fdl_enqueue (this, stub); - -        return 0; -} -""" - -LEN_DICT_TEMPLATE = """ -		if (@SRC@) { -			data_pair_t *memb; -			for (memb = @SRC@->members_list; memb; memb = memb->next) { -				meta_len += sizeof(int); -				meta_len += strlen(memb->key) + 1; -				meta_len += sizeof(int); -				meta_len += memb->value->len; -			} -		} -		meta_len += sizeof(int); -""" - -LEN_GFID_TEMPLATE = """ -        meta_len += 16; -""" - -LEN_INTEGER_TEMPLATE = """ -        meta_len += sizeof (@SRC@); -""" - -# 16 for gfid, 16 for pargfid, 1 for flag, 0/1 for terminating NUL -LEN_LOC_TEMPLATE = """ -        if (@SRC@.name) { -                meta_len += (strlen (@SRC@.name) + 34); -        } else { -                meta_len += 33; -        } -""" - -LEN_STRING_TEMPLATE = """ -        if (@SRC@) { -                meta_len += (strlen (@SRC@) + 1); -        } else { -                meta_len += 1; -        } -""" - -LEN_VECTOR_TEMPLATE = """ -        meta_len += sizeof(size_t); -        data_len += iov_length (@VEC@, @CNT@); -""" - -LEN_IATT_TEMPLATE = """ -		meta_len += sizeof(@SRC@.ia_prot); -		meta_len += sizeof(@SRC@.ia_uid); -		meta_len += sizeof(@SRC@.ia_gid); -		meta_len += sizeof(@SRC@.ia_atime); -		meta_len += sizeof(@SRC@.ia_atime_nsec); -		meta_len += sizeof(@SRC@.ia_mtime); -		meta_len += sizeof(@SRC@.ia_mtime_nsec); -""" - -SERLZ_DICT_TEMPLATE = """ -        if (@SRC@) { -			data_pair_t *memb; -			for (memb = @SRC@->members_list; memb; memb = memb->next) { -				*((int *)(meta_buf+offset)) = strlen(memb->key) + 1; -				offset += sizeof(int); -				strcpy (meta_buf+offset, memb->key); -				offset += strlen(memb->key) + 1; -				*((int *)(meta_buf+offset)) = memb->value->len; -				offset += sizeof(int); -				memcpy (meta_buf+offset, memb->value->data, memb->value->len); -				offset += memb->value->len; -			} -        } -		*((int *)(meta_buf+offset)) = 0; -		offset += sizeof(int); -""" - -SERLZ_GFID_TEMPLATE = """ -        memcpy (meta_buf+offset, @SRC@->inode->gfid, 16); -        offset += 16; -""" - -SERLZ_INTEGER_TEMPLATE = """ -        memcpy (meta_buf+offset, &@SRC@, sizeof(@SRC@)); -        offset += sizeof(@SRC@); -""" - -SERLZ_LOC_TEMPLATE = """ -        memcpy (meta_buf+offset, @SRC@.gfid, 16); -        offset += 16; -        memcpy (meta_buf+offset, @SRC@.pargfid, 16); -        offset += 16; -        if (@SRC@.name) { -                *(meta_buf+offset) = 1; -				++offset; -                strcpy (meta_buf+offset, @SRC@.name); -                offset += (strlen (@SRC@.name) + 1); -        } else { -                *(meta_buf+offset) = 0; -				++offset; -        } -""" - -SERLZ_STRING_TEMPLATE = """ -        if (@SRC@) { -                *(meta_buf+offset) = 1; -				++offset; -                strcpy (meta_buf+offset, @SRC@); -                offset += strlen(@SRC@); -        } else { -                *(meta_buf+offset) = 0; -				++offset; -        } -""" - -SERLZ_VECTOR_TEMPLATE = """ -        *((size_t *)(meta_buf+offset)) = iov_length (@VEC@, @CNT@); -        offset += sizeof(size_t); -        int32_t i; -        for (i = 0; i < @CNT@; ++i) { -                memcpy (data_buf, @VEC@[i].iov_base, @VEC@[i].iov_len); -                data_buf += @VEC@[i].iov_len; -        } -""" - -# We don't need to save all of the fields - only those affected by chown, -# chgrp, chmod, and utime. -SERLZ_IATT_TEMPLATE = """ -		*((ia_prot_t *)(meta_buf+offset)) = @SRC@.ia_prot; -		offset += sizeof(@SRC@.ia_prot); -		*((uint32_t *)(meta_buf+offset)) = @SRC@.ia_uid; -		offset += sizeof(@SRC@.ia_uid); -		*((uint32_t *)(meta_buf+offset)) = @SRC@.ia_gid; -		offset += sizeof(@SRC@.ia_gid); -		*((uint32_t *)(meta_buf+offset)) = @SRC@.ia_atime; -		offset += sizeof(@SRC@.ia_atime); -		*((uint32_t *)(meta_buf+offset)) = @SRC@.ia_atime_nsec; -		offset += sizeof(@SRC@.ia_atime_nsec); -		*((uint32_t *)(meta_buf+offset)) = @SRC@.ia_mtime; -		offset += sizeof(@SRC@.ia_mtime); -		*((uint32_t *)(meta_buf+offset)) = @SRC@.ia_mtime_nsec; -		offset += sizeof(@SRC@.ia_mtime_nsec); -""" - -typemap = { -	'dict_t *':				( LEN_DICT_TEMPLATE,	SERLZ_DICT_TEMPLATE), -	'fd_t *':				( LEN_GFID_TEMPLATE,	SERLZ_GFID_TEMPLATE), -	'dev_t':				( LEN_INTEGER_TEMPLATE,	SERLZ_INTEGER_TEMPLATE), -	'gf_xattrop_flags_t':	( LEN_INTEGER_TEMPLATE,	SERLZ_INTEGER_TEMPLATE), -	'int32_t':				( LEN_INTEGER_TEMPLATE,	SERLZ_INTEGER_TEMPLATE), -	'mode_t':				( LEN_INTEGER_TEMPLATE, SERLZ_INTEGER_TEMPLATE), -	'off_t':				( LEN_INTEGER_TEMPLATE,	SERLZ_INTEGER_TEMPLATE), -	'size_t':				( LEN_INTEGER_TEMPLATE,	SERLZ_INTEGER_TEMPLATE), -	'uint32_t':				( LEN_INTEGER_TEMPLATE,	SERLZ_INTEGER_TEMPLATE), -	'loc_t *':				( LEN_LOC_TEMPLATE,		SERLZ_LOC_TEMPLATE), -	'const char *':			( LEN_STRING_TEMPLATE,	SERLZ_STRING_TEMPLATE), -	'struct iatt *':		( LEN_IATT_TEMPLATE,	SERLZ_IATT_TEMPLATE), -} - -def get_special_subs (args): -	len_code = "" -	ser_code = "" -	for arg in args: -		if (arg[0] != 'fop-arg') or (len(arg) < 4): -			continue -		# Let this throw an exception if we get an unknown field name.  The -		# broken build will remind whoever messed with the stub code that a -		# corresponding update is needed here. -		if arg[3] == "vector": -			# Make it as obvious as possible that this is a special case. -			len_code += LEN_VECTOR_TEMPLATE \ -				.replace("@VEC@", "stub->args.vector") \ -				.replace("@CNT@", "stub->args.count") -			ser_code += SERLZ_VECTOR_TEMPLATE \ -				.replace("@VEC@", "stub->args.vector") \ -				.replace("@CNT@", "stub->args.count") -		else: -			len_tmpl, ser_tmpl = typemap[arg[2]] -			src = "stub->args.%s" % arg[3] -			len_code += len_tmpl.replace("@SRC@", src) -			ser_code += ser_tmpl.replace("@SRC@", src) -	return len_code, ser_code - -# Mention those fops in the selective_generate table, for which -# only a few common functions will be generated, and mention those -# functions. Rest of the functions can be customized -selective_generate = { -		"ipc":			"len,serialize", -	} - -def gen_fdl (): -	entrypoints = [] -	for name, value in ops.items(): -		if "journal" not in [ x[0] for x in value ]: -			continue - -		# generate all functions for all the fops -		# except for the ones in selective_generate for which -		# generate only the functions mentioned in the -		# selective_generate table -		gen_funcs = "len,serialize,callback,continue,fop" -		if name in selective_generate: -			gen_funcs = selective_generate[name].split(",") - -		len_code, ser_code = get_special_subs(value) -		fop_subs[name]["@LEN_CODE@"] = len_code[:-1] -		fop_subs[name]["@SER_CODE@"] = ser_code[:-1] -		if 'len' in gen_funcs: -			print(generate(LEN_TEMPLATE, name, fop_subs)) -		if 'serialize' in gen_funcs: -			print(generate(SER_TEMPLATE, name, fop_subs)) -		if name == 'writev': -			print("#define DESTAGE_ASYNC") -		if 'callback' in gen_funcs: -			print(generate(CBK_TEMPLATE, name, cbk_subs)) -		if 'continue' in gen_funcs: -			print(generate(CONTINUE_TEMPLATE, name, fop_subs)) -		if 'fop' in gen_funcs: -			print(generate(FOP_TEMPLATE, name, fop_subs)) -		if name == 'writev': -			print("#undef DESTAGE_ASYNC") -		entrypoints.append(name) -	print("struct xlator_fops fops = {") -	for ep in entrypoints: -		print("\t.%s = fdl_%s," % (ep, ep)) -	print("};") - -for l in open(sys.argv[1], 'r').readlines(): -	if l.find('#pragma generate') != -1: -		print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") -		gen_fdl() -		print("/* END GENERATED CODE */") -	else: -		print(l[:-1]) diff --git a/xlators/experimental/fdl/src/gen_recon.py b/xlators/experimental/fdl/src/gen_recon.py deleted file mode 100755 index 0766f61320a..00000000000 --- a/xlators/experimental/fdl/src/gen_recon.py +++ /dev/null @@ -1,218 +0,0 @@ -#!/usr/bin/python3 - -from __future__ import print_function -import os -import re -import string -import sys - -curdir = os.path.dirname (sys.argv[0]) -gendir = os.path.join (curdir, '../../../../libglusterfs/src') -sys.path.append (gendir) -from generator import ops, fop_subs, cbk_subs, generate - -# See the big header comment at the start of gen_fdl.py to see how the stages -# fit together.  The big difference here is that *all* of the C code is in the -# template file as labelled fragments, instead of as Python strings.  That -# makes it much easier to edit in one place, with proper syntax highlighting -# and indentation. -# -#   Stage 1 uses type-specific fragments to generate FUNCTION_BODY, instead of -#   LEN_*_TEMPLATE and SERLZ_*_TEMPLATE to generate LEN_CODE and SER_CODE. -# -#   Stage 2 uses the FOP and CASE fragments instead of RECON_TEMPLATE and -#   FOP_TEMPLATE.  The expanded FOP code (including FUNCTION_BODY substitution -#   in the middle of each function) is emitted immediately; the expanded CASE -#   code is saved for the next stage. -# -#   Stage 3 uses the PROLOG and EPILOG fragments, with the expanded CASE code -#   in the middle of EPILOG, to generate the whole output file. -# -# Another way of looking at it is to consider how the fragments appear in -# the final output: -# -#   PROLOG -#   FOP (expanded for CREATE) -#       FOP before FUNCTION_BODY -#       LOC, INTEGER, GFID, etc. (one per arg, by type) -#       FOP after FUNCTION_BODY -#   FOP (expanded for WRITEV) -#       FOP before FUNCTION_BODY -#       GFID, VECTOR, etc. (one per arg, by type) -#       FOP after FUNCTION_BODY -#   (more FOPs) -#   EPILOG -#       EPILOG before CASE -#       CASE statements (one per fop) -#       EPILOG after CASE - -typemap = { -	'dict_t *':				"DICT", -	'fd_t *':				"FD", -	'dev_t':				"DOUBLE", -	'gf_xattrop_flags_t':	"INTEGER", -	'int32_t':				"INTEGER", -	'mode_t':				"INTEGER", -	'off_t':				"DOUBLE", -	'size_t':				"DOUBLE", -	'uint32_t':				"INTEGER", -	'loc_t *':				"LOC", -	'const char *':			"STRING", -	'struct iovec *':		"VECTOR", -	'struct iatt *':		"IATT", -	'struct iobref *':		"IOBREF", -} - -def get_special_subs (name, args, fop_type): -	code = "" -	cleanups = "" -	links = "" -	s_args = [] -	for arg in args: -		if arg[0] == 'extra': -			code += "\t%s %s;\n\n" % (arg[2], arg[1]) -			s_args.append(arg[3]) -			continue -		if arg[0] == 'link': -			links += fragments["LINK"].replace("@INODE_ARG@", arg[1])	\ -									  .replace("@IATT_ARG@", arg[2]) -			continue -		if arg[0] != 'fop-arg': -			continue -		if (name, arg[1]) == ('writev', 'count'): -			# Special case: just skip this.  We can't mark it as 'nosync' -			# because of the way the translator and dumper generators look for -			# that after 'stub-name' which we don't define.  Instead of adding a -			# bunch of generic infrastructure for this one case, just pound it -			# here. -			continue -		recon_type = typemap[arg[2]] -		# print "/* %s.%s => %s (%s)*/" % (name, arg[1], recon_type, fop_type) -		if (name == "create") and (arg[1] == "fd"): -			# Special case: fd for create is new, not looked up. -			# print "/* change to NEW_FD */" -			recon_type = "NEW_FD" -		elif (recon_type == "LOC") and (fop_type == "entry-op"): -			# Need to treat this differently for inode vs. entry ops. -			# Special case: link source is treated like inode-op. -			if (name != "link") or (arg[1] != "oldloc"): -				# print "/* change to PARENT_LOC */" -				recon_type = "PARENT_LOC" -		code += fragments[recon_type].replace("@ARGNAME@", arg[1])		\ -									 .replace("@ARGTYPE@", arg[2]) -		cleanup_key = recon_type + "_CLEANUP" -		if cleanup_key in fragments: -			new_frag = fragments[cleanup_key].replace("@ARGNAME@", arg[1]) -			# Make sure these get added in *reverse* order.  Otherwise, a -			# failure for an earlier argument might goto a label that falls -			# through to the cleanup code for a variable associated with a -			# later argument, but that variable might not even have been -			# *declared* (let alone initialized) yet.  Consider the following -			# case. -			# -			#         process argument A (on failure goto cleanup_A) -			#         set error label to cleanup_A -			# -			#         declare pointer variable for argument B -			#         process argument B (on failure goto cleanup_B) -			# -			#     cleanup_A: -			#         /* whatever */ -			#     cleanup_B: -			#         free pointer variable <= "USED BUT NOT SET" error here -			# -			# By adding these in reverse order, we ensure that cleanup_B is -			# actually *before* cleanup_A, and nothing will try to do the free -			# until we've actually attempted processing of B. -			cleanups = new_frag + cleanups -		if 'nosync' in arg[4:]: -			code += "\t(void)%s;\n" % arg[1]; -			continue -		if arg[2] in ("loc_t *", "struct iatt *"): -			# These are passed as pointers to the syncop, but they're actual -			# structures in the generated code. -			s_args.append("&"+arg[1]); -		else: -			s_args.append(arg[1]) -	# We have to handle a couple of special cases here, because some n00b -	# defined the syncops with a different argument order than the fops they're -	# based on. -	if name == 'writev': -		# Swap 'flags' and 'iobref'.  Also, we need to add the iov count, which -		# is not stored in or read from the journal.  There are other ways to -		# do that, but this is the only place we need anything similar and we -		# already have to treat it as a special case so this is simplest. -	       s_args_str = 'fd, &vector, 1, off, iobref, flags, &preop, &postop, xdata' -	elif name == 'symlink': -		# Swap 'linkpath' and 'loc'. -		s_args_str = '&loc, linkpath, &iatt, xdata' -	elif name == 'xattrop': -	        s_args_str = '&loc, flags, dict, xdata, NULL' -	elif name == 'fxattrop': -	        s_args_str = 'fd, flags, dict, xdata, NULL' -	else: -		s_args_str = ', '.join(s_args) -	return code, links, s_args_str, cleanups - -# TBD: probably need to generate type-specific cleanup code as well - e.g. -# fd_unref for an fd_t, loc_wipe for a loc_t, and so on.  All of these -# generated CLEANUP fragments will go at the end of the function, with goto -# labels.  Meanwhile, the error-checking part of each type-specific fragment -# (e.g. LOC or FD) will need to update the indirect label that we jump to when -# an error is detected.  This will probably get messy. -def gen_functions (): -	code = "" -	for name, value in ops.items(): -		fop_type = [ x[1] for x in value if x[0] == "journal" ] -		if not fop_type: -			continue -		body, links, syncop_args, cleanups = get_special_subs (name, value, -															   fop_type[0]) -		fop_subs[name]["@FUNCTION_BODY@"] = body -		fop_subs[name]["@LINKS@"] = links -		fop_subs[name]["@SYNCOP_ARGS@"] = syncop_args -		fop_subs[name]["@CLEANUPS@"] = cleanups -		if name == "writev": -			# Take advantage of the fact that, *during reconciliation*, the -			# vector is always a single element.  In normal I/O it's not. -			fop_subs[name]["@SUCCESS_VALUE@"] = "vector.iov_len" -		else: -			fop_subs[name]["@SUCCESS_VALUE@"] = "GFAPI_SUCCESS" -		# Print the FOP fragment with @FUNCTION_BODY@ in the middle. -		code += generate(fragments["FOP"], name, fop_subs) -	return code - -def gen_cases (): -	code = "" -	for name, value in ops.items(): -		if "journal" not in [ x[0] for x in value ]: -			continue -		# Add the CASE fragment for this fop. -		code += generate(fragments["CASE"], name, fop_subs) -	return code - -def load_fragments (path="recon-tmpl.c"): -	pragma_re = re.compile('pragma fragment (.*)') -	cur_symbol = None -	cur_value = "" -	result = {} -	for line in open(path, "r").readlines(): -		m = pragma_re.search(line) -		if m: -			if cur_symbol: -				result[cur_symbol] = cur_value -			cur_symbol = m.group(1) -			cur_value = "" -		else: -			cur_value += line -	if cur_symbol: -		result[cur_symbol] = cur_value -	return result - -if __name__ == "__main__": -	fragments = load_fragments(sys.argv[1]) -	print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") -	print(fragments["PROLOG"]) -	print(gen_functions()) -	print(fragments["EPILOG"].replace("@SWITCH_BODY@", gen_cases())) -	print("/* END GENERATED CODE */") diff --git a/xlators/experimental/fdl/src/logdump.c b/xlators/experimental/fdl/src/logdump.c deleted file mode 100644 index 6fbc5218d47..00000000000 --- a/xlators/experimental/fdl/src/logdump.c +++ /dev/null @@ -1,51 +0,0 @@ -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/mman.h> - -extern int -fdl_dump(char **, char **); - -int -main(int argc, char **argv) -{ -    int meta_fd = (-1); -    char *meta_buf = NULL; -    int data_fd = (-1); -    char *data_buf = NULL; - -    meta_fd = open(argv[1], O_RDONLY); -    if (meta_fd < 0) { -        perror("open"); -        return EXIT_FAILURE; -    } - -    /* TBD: get proper length */ -    meta_buf = mmap(NULL, 1048576, PROT_READ, MAP_PRIVATE, meta_fd, 0); -    if (meta_buf == MAP_FAILED) { -        perror("mmap"); -        return EXIT_FAILURE; -    } - -    data_fd = open(argv[2], O_RDONLY); -    if (data_fd < 0) { -        perror("open"); -        return EXIT_FAILURE; -    } - -    /* TBD: get proper length */ -    data_buf = mmap(NULL, 1048576, PROT_READ, MAP_PRIVATE, data_fd, 0); -    if (data_buf == MAP_FAILED) { -        perror("mmap"); -        return EXIT_FAILURE; -    } - -    for (;;) { -        if (!fdl_dump(&meta_buf, &data_buf)) { -            break; -        } -    } - -    return EXIT_SUCCESS; -} diff --git a/xlators/experimental/fdl/src/recon-tmpl.c.in b/xlators/experimental/fdl/src/recon-tmpl.c.in deleted file mode 100644 index 5115dfd5c75..00000000000 --- a/xlators/experimental/fdl/src/recon-tmpl.c.in +++ /dev/null @@ -1,297 +0,0 @@ -#pragma fragment PROLOG -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "glusterfs.h" -#include "iatt.h" -#include "syncop.h" -#include "xlator.h" -#include "glfs-internal.h" - -#include "fdl.h" - -#define GFAPI_SUCCESS 0 - -inode_t * -recon_get_inode(glfs_t *fs, uuid_t gfid) -{ -    inode_t *inode; -    loc_t loc = { -        NULL, -    }; -    struct iatt iatt; -    int ret; -    inode_t *newinode; - -    inode = inode_find(fs->active_subvol->itable, gfid); -    if (inode) { -        printf("=== FOUND %s IN TABLE\n", uuid_utoa(gfid)); -        return inode; -    } - -    loc.inode = inode_new(fs->active_subvol->itable); -    if (!loc.inode) { -        return NULL; -    } -    gf_uuid_copy(loc.inode->gfid, gfid); -    gf_uuid_copy(loc.gfid, gfid); - -    printf("=== DOING LOOKUP FOR %s\n", uuid_utoa(gfid)); - -    ret = syncop_lookup(fs->active_subvol, &loc, &iatt, NULL, NULL, NULL); -    if (ret != GFAPI_SUCCESS) { -        fprintf(stderr, "syncop_lookup failed (%d)\n", ret); -        return NULL; -    } - -    newinode = inode_link(loc.inode, NULL, NULL, &iatt); -    if (newinode) { -        inode_lookup(newinode); -    } - -    return newinode; -} - -#pragma fragment DICT -dict_t *@ARGNAME@; - -@ARGNAME@ = dict_new(); -if (!@ARGNAME@) { -    goto *err_label; -} -err_label = &&cleanup_@ARGNAME@; - -{ -    int key_len, data_len; -    char *key_ptr; -    int garbage; -    for (;;) { -        key_len = *((int *)new_meta); -        new_meta += sizeof(int); -        if (!key_len) { -            break; -        } -        key_ptr = new_meta; -        new_meta += key_len; -        data_len = *((int *)new_meta); -        new_meta += sizeof(int); -        garbage = dict_set_static_bin(@ARGNAME@, key_ptr, new_meta, data_len); -        /* TBD: check error from dict_set_static_bin */ -        (void)garbage; -        new_meta += data_len; -    } -} - -#pragma fragment DICT_CLEANUP -cleanup_@ARGNAME@ : dict_unref(@ARGNAME@); - -#pragma fragment DOUBLE -@ARGTYPE@ @ARGNAME@ = *((@ARGTYPE@ *)new_meta); -new_meta += sizeof(uint64_t); - -#pragma fragment FD -inode_t *@ARGNAME@_ino; -fd_t *@ARGNAME@; - -@ARGNAME@_ino = recon_get_inode(fs, *((uuid_t *)new_meta)); -new_meta += 16; -if (!@ARGNAME@_ino) { -    goto *err_label; -} -err_label = &&cleanup_@ARGNAME@_ino; - -@ARGNAME@ = fd_anonymous(@ARGNAME@_ino); -if (!@ARGNAME@) { -    goto *err_label; -} -err_label = &&cleanup_@ARGNAME@; - -#pragma fragment FD_CLEANUP -cleanup_@ARGNAME@ : fd_unref(@ARGNAME@); -cleanup_@ARGNAME@_ino : inode_unref(@ARGNAME@_ino); - -#pragma fragment NEW_FD -/* - * This pseudo-type is only used for create, and in that case we know - * we'll be using loc.inode, so it's not worth generalizing to take an - * extra argument. - */ -fd_t *@ARGNAME@ = fd_anonymous(loc.inode); - -if (!fd) { -    goto *err_label; -} -err_label = &&cleanup_@ARGNAME@; -new_meta += 16; - -#pragma fragment NEW_FD_CLEANUP -cleanup_@ARGNAME@ : fd_unref(@ARGNAME@); - -#pragma fragment INTEGER -@ARGTYPE@ @ARGNAME@ = *((@ARGTYPE@ *)new_meta); - -new_meta += sizeof(@ARGTYPE@); - -#pragma fragment LOC -loc_t @ARGNAME@ = { -    NULL, -}; - -@ARGNAME@.inode = recon_get_inode(fs, *((uuid_t *)new_meta)); -if (!@ARGNAME@.inode) { -    goto *err_label; -} -err_label = &&cleanup_@ARGNAME@; -gf_uuid_copy(@ARGNAME@.gfid, @ARGNAME@.inode->gfid); -new_meta += 16; -new_meta += 16; /* skip over pargfid */ -if (*(new_meta++)) { -    @ARGNAME@.name = new_meta; -    new_meta += strlen(new_meta) + 1; -} - -#pragma fragment LOC_CLEANUP -cleanup_@ARGNAME@ : loc_wipe(&@ARGNAME@); - -#pragma fragment PARENT_LOC -loc_t @ARGNAME@ = { -    NULL, -}; - -new_meta += 16; /* skip over gfid */ -@ARGNAME@.parent = recon_get_inode(fs, *((uuid_t *)new_meta)); -if (!@ARGNAME@.parent) { -    goto *err_label; -} -err_label = &&cleanup_@ARGNAME@; -gf_uuid_copy(@ARGNAME@.pargfid, @ARGNAME@.parent->gfid); -new_meta += 16; -if (!*(new_meta++)) { -    goto *err_label; -} -@ARGNAME@.name = new_meta; -new_meta += strlen(new_meta) + 1; - -@ARGNAME@.inode = inode_new(fs->active_subvol->itable); -if (!@ARGNAME@.inode) { -    goto *err_label; -} - -#pragma fragment PARENT_LOC_CLEANUP -cleanup_@ARGNAME@ : loc_wipe(&@ARGNAME@); - -#pragma fragment STRING -char *@ARGNAME@; -if (*(new_meta++)) { -    @ARGNAME@ = new_meta; -    new_meta += (strlen(new_meta) + 1); -} else { -    goto *err_label; -} - -#pragma fragment VECTOR -struct iovec @ARGNAME@; - -@ARGNAME@.iov_len = *((size_t *)new_meta); -new_meta += sizeof(@ARGNAME@.iov_len); -@ARGNAME@.iov_base = new_data; -new_data += @ARGNAME@.iov_len; - -#pragma fragment IATT -struct iatt @ARGNAME@; -{ -    @ARGNAME@.ia_prot = *((ia_prot_t *)new_meta); -    new_meta += sizeof(ia_prot_t); -    uint32_t *myints = (uint32_t *)new_meta; -    @ARGNAME@.ia_uid = myints[0]; -    @ARGNAME@.ia_gid = myints[1]; -    @ARGNAME@.ia_atime = myints[2]; -    @ARGNAME@.ia_atime_nsec = myints[3]; -    @ARGNAME@.ia_mtime = myints[4]; -    @ARGNAME@.ia_mtime_nsec = myints[5]; -    new_meta += sizeof(*myints) * 6; -} - -#pragma fragment IOBREF -struct iobref *@ARGNAME@; - -@ARGNAME@ = iobref_new(); -if (!@ARGNAME@) { -    goto *err_label; -} -err_label = &&cleanup_@ARGNAME@; - -#pragma fragment IOBREF_CLEANUP -cleanup_@ARGNAME@ : iobref_unref(@ARGNAME@); - -#pragma fragment LINK -/* TBD: check error */ -inode_t *new_inode = inode_link(@INODE_ARG@, NULL, NULL, @IATT_ARG@); -if (new_inode) { -    inode_lookup(new_inode); -} - -#pragma fragment FOP -int fdl_replay_@NAME@(glfs_t *fs, char **old_meta, char **old_data) -{ -    char *new_meta = *old_meta; -    char *new_data = *old_data; -    int ret; -    int status = 0xbad; -    void *err_label = &&done; - -    @FUNCTION_BODY@ - -    ret = syncop_@NAME@(fs->active_subvol, @SYNCOP_ARGS@, NULL); -    if (ret !=@SUCCESS_VALUE@) { -        fprintf(stderr, "syncop_@NAME@ returned %d", ret); -        goto *err_label; -    } - -    @LINKS@ - -    status = 0; - -    @CLEANUPS@ - -     done : *old_meta = new_meta; -    *old_data = new_data; -    return status; -} - -#pragma fragment CASE -case GF_FOP_@UPNAME@: -    printf("=== GF_FOP_@UPNAME@\n"); -    if (fdl_replay_@NAME@(fs, &new_meta, &new_data) != 0) { -        goto done; -    } -    recognized = 1; -    break; - -#pragma fragment EPILOG -    int -    recon_execute(glfs_t *fs, char **old_meta, char **old_data) -    { -        char *new_meta = *old_meta; -        char *new_data = *old_data; -        int recognized = 0; -        event_header_t *eh; - -        eh = (event_header_t *)new_meta; -        new_meta += sizeof(*eh); - -        /* TBD: check event_type instead of assuming NEW_REQUEST */ - -        switch (eh->fop_type) { -            @SWITCH_BODY@ - -            default : printf("unknown fop %u\n", eh->fop_type); -        } - -    done: -        *old_meta = new_meta; -        *old_data = new_data; -        return recognized; -    } diff --git a/xlators/experimental/fdl/src/recon.c b/xlators/experimental/fdl/src/recon.c deleted file mode 100644 index 51c57d4ac22..00000000000 --- a/xlators/experimental/fdl/src/recon.c +++ /dev/null @@ -1,89 +0,0 @@ -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/mman.h> - -#include <glusterfs/glusterfs.h> -#include <glusterfs/fd.h> -#include <glusterfs/syncop.h> -#include "glfs-internal.h" - -#define GFAPI_SUCCESS 0 - -extern int -recon_execute(glfs_t *, char **, char **); - -int -main(int argc, char **argv) -{ -    glfs_t *fs; -    int ret; -    int meta_fd = (-1); -    char *meta_buf = NULL; -    int data_fd = (-1); -    char *data_buf = NULL; - -    fs = glfs_new("whocares"); -    if (!fs) { -        fprintf(stderr, "glfs_new failed\n"); -        return EXIT_FAILURE; -    } - -    if (getenv("RECON_DEBUG")) { -        ret = glfs_set_logging(fs, "/dev/stderr", 7); -    } else { -        ret = glfs_set_logging(fs, "/dev/null", 0); -    } - -    if (ret != GFAPI_SUCCESS) { -        fprintf(stderr, "glfs_set_logging failed (%d)\n", errno); -        return EXIT_FAILURE; -    } - -    ret = glfs_set_volfile(fs, argv[1]); -    if (ret != GFAPI_SUCCESS) { -        fprintf(stderr, "glfs_set_volfile failed (%d)\n", errno); -        return EXIT_FAILURE; -    } - -    ret = glfs_init(fs); -    if (ret != GFAPI_SUCCESS) { -        fprintf(stderr, "glfs_init failed (%d)\n", errno); -        return EXIT_FAILURE; -    } - -    meta_fd = open(argv[2], O_RDONLY); -    if (meta_fd < 0) { -        perror("open"); -        return EXIT_FAILURE; -    } - -    /* TBD: get proper length */ -    meta_buf = mmap(NULL, 1048576, PROT_READ, MAP_PRIVATE, meta_fd, 0); -    if (meta_buf == MAP_FAILED) { -        perror("mmap"); -        return EXIT_FAILURE; -    } - -    data_fd = open(argv[3], O_RDONLY); -    if (data_fd < 0) { -        perror("open"); -        return EXIT_FAILURE; -    } - -    /* TBD: get proper length */ -    data_buf = mmap(NULL, 1048576, PROT_READ, MAP_PRIVATE, data_fd, 0); -    if (data_buf == MAP_FAILED) { -        perror("mmap"); -        return EXIT_FAILURE; -    } - -    for (;;) { -        if (!recon_execute(fs, &meta_buf, &data_buf)) { -            break; -        } -    } - -    return EXIT_SUCCESS; -} diff --git a/xlators/experimental/jbr-client/Makefile.am b/xlators/experimental/jbr-client/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/jbr-client/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/jbr-client/src/Makefile.am b/xlators/experimental/jbr-client/src/Makefile.am deleted file mode 100644 index c71f5ff1e83..00000000000 --- a/xlators/experimental/jbr-client/src/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -if WITH_SERVER -xlator_LTLIBRARIES = jbrc.la -endif -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental - -nodist_jbrc_la_SOURCES = jbrc-cg.c -CLEANFILES = $(nodist_jbrc_la_SOURCES) - -jbrc_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -jbrc_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -noinst_HEADERS = $(top_srcdir)/xlators/lib/src/libxlator.h \ -	$(top_srcdir)/glusterfsd/src/glusterfsd.h \ -	jbrc.h jbr-messages.h - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/xlators/lib/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -	-I$(top_srcdir)/rpc/rpc-lib/src - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -JBRC_PREFIX	= $(top_srcdir)/xlators/experimental/jbr-client/src -JBRC_GEN_FOPS	= $(JBRC_PREFIX)/gen-fops.py -JBRC_TEMPLATES	= $(JBRC_PREFIX)/fop-template.c.in -JBRC_WRAPPER	= $(JBRC_PREFIX)/jbrc.c -noinst_PYTHON	= $(JBRC_GEN_FOPS) -EXTRA_DIST	= $(JBRC_TEMPLATES) $(JBRC_WRAPPER) - -jbrc-cg.c: $(JBRC_GEN_FOPS) $(JBRC_TEMPLATES) $(JBRC_WRAPPER) -	$(PYTHON) $(JBRC_GEN_FOPS) $(JBRC_TEMPLATES) $(JBRC_WRAPPER) > $@ - -uninstall-local: -	rm -f $(DESTDIR)$(xlatordir)/jbr.so diff --git a/xlators/experimental/jbr-client/src/fop-template.c.in b/xlators/experimental/jbr-client/src/fop-template.c.in deleted file mode 100644 index 9732badc794..00000000000 --- a/xlators/experimental/jbr-client/src/fop-template.c.in +++ /dev/null @@ -1,102 +0,0 @@ -/* template-name fop */ -int32_t jbrc_@NAME@(call_frame_t *frame, xlator_t *this, @LONG_ARGS@) -{ -    jbrc_local_t *local = NULL; -    xlator_t *target_xl = ACTIVE_CHILD(this); - -    local = mem_get(this->local_pool); -    if (!local) { -        goto err; -    } - -    local->stub = fop_@NAME@_stub(frame, jbrc_@NAME@_continue, @SHORT_ARGS@); -    if (!local->stub) { -        goto err; -    } -    local->curr_xl = target_xl; -    local->scars = 0; - -    frame->local = local; -    STACK_WIND_COOKIE(frame, jbrc_@NAME@_cbk, target_xl, target_xl, -                      target_xl->fops->@NAME@, @SHORT_ARGS@); -    return 0; - -err: -    if (local) { -        mem_put(local); -    } -    STACK_UNWIND_STRICT(@NAME@, frame, -1, ENOMEM, @ERROR_ARGS@); -    return 0; -} - -/* template-name cbk */ -int32_t jbrc_@NAME@_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                          int32_t op_ret, int32_t op_errno, @LONG_ARGS@) -{ -    jbrc_local_t *local = frame->local; -    xlator_t *last_xl = cookie; -    xlator_t *next_xl; -    jbrc_private_t *priv = this->private; -    struct timespec spec; - -    if (op_ret != (-1)) { -        if (local->scars) { -            gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_RETRY_MSG, -                   HILITE("retried %p OK"), frame->local); -        } -        priv->active = last_xl; -        goto unwind; -    } -    if ((op_errno != EREMOTE) && (op_errno != ENOTCONN)) { -        goto unwind; -    } - -    /* TBD: get leader ID from xdata? */ -    next_xl = next_xlator(this, last_xl); -    /* -     * We can't just give up after we've tried all bricks, because it's -     * quite likely that a new leader election just hasn't finished yet. -     * We also shouldn't retry endlessly, and especially not at a high -     * rate, but that's good enough while we work on other things. -     * -     * TBD: implement slow/finite retry via a worker thread -     */ -    if (!next_xl || (local->scars >= SCAR_LIMIT)) { -        gf_msg(this->name, GF_LOG_DEBUG, 0, J_MSG_RETRY_MSG, -               HILITE("ran out of retries for %p"), frame->local); -        goto unwind; -    } - -    local->curr_xl = next_xl; -    local->scars += 1; -    spec.tv_sec = 1; -    spec.tv_nsec = 0; -    /* -     * WARNING -     * -     * Just calling gf_timer_call_after like this leaves open the -     * possibility that writes will get reordered, if a first write is -     * rescheduled and then a second comes along to find an updated -     * priv->active before the first actually executes.  We might need to -     * implement a stricter (and more complicated) queuing mechanism to -     * ensure absolute consistency in this case. -     */ -    if (gf_timer_call_after(this->ctx, spec, jbrc_retry_cb, local)) { -        return 0; -    } - -unwind: -    call_stub_destroy(local->stub); -    STACK_UNWIND_STRICT(@NAME@, frame, op_ret, op_errno, @SHORT_ARGS@); -    return 0; -} - -/* template-name cont-func */ -int32_t jbrc_@NAME@_continue(call_frame_t *frame, xlator_t *this, @LONG_ARGS@) -{ -    jbrc_local_t *local = frame->local; - -    STACK_WIND_COOKIE(frame, jbrc_@NAME@_cbk, local->curr_xl, local->curr_xl, -                      local->curr_xl->fops->@NAME@, @SHORT_ARGS@); -    return 0; -} diff --git a/xlators/experimental/jbr-client/src/gen-fops.py b/xlators/experimental/jbr-client/src/gen-fops.py deleted file mode 100755 index a5ddf577fbe..00000000000 --- a/xlators/experimental/jbr-client/src/gen-fops.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/python3 - -from __future__ import print_function -import os -import re -import string -import sys - -curdir = os.path.dirname(sys.argv[0]) -gendir = os.path.join(curdir, '../../../../libglusterfs/src') -sys.path.append(gendir) -from generator import ops, fop_subs, cbk_subs, generate - -# We really want the callback argument list, even when we're generating fop -# code, so we propagate here. -# TBD: this should probably be right in generate.py -for k, v in cbk_subs.items(): -	fop_subs[k]['@ERROR_ARGS@'] = v['@ERROR_ARGS@'] - -# Stolen from old codegen.py -def load_templates (path): -	templates = {} -	tmpl_re = re.compile("/\* template-name (.*) \*/") -	templates = {} -	t_name = None -	for line in open(path, "r").readlines(): -		if not line: -			break -		m = tmpl_re.match(line) -		if m: -			if t_name: -				templates[t_name] = ''.join(t_contents) -			t_name = m.group(1).strip() -			t_contents = [] -		elif t_name: -			t_contents.append(line) -	if t_name: -		templates[t_name] = ''.join(t_contents) -	return templates - -# Stolen from gen_fdl.py -def gen_client (templates): -	for name, value in ops.items(): -		if name == 'getspec': -			# It's not real if it doesn't have a stub function. -			continue -		print(generate(templates['cbk'], name, cbk_subs)) -		print(generate(templates['cont-func'], name, fop_subs)) -		print(generate(templates['fop'], name, fop_subs)) - -tmpl = load_templates(sys.argv[1]) -for l in open(sys.argv[2], 'r').readlines(): -	if l.find('#pragma generate') != -1: -		print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") -		gen_client(tmpl) -		print("/* END GENERATED CODE */") -	else: -		print(l[:-1]) diff --git a/xlators/experimental/jbr-client/src/jbr-messages.h b/xlators/experimental/jbr-client/src/jbr-messages.h deleted file mode 100644 index 608e024f920..00000000000 --- a/xlators/experimental/jbr-client/src/jbr-messages.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -  Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _JBR_MESSAGES_H_ -#define _JBR_MESSAGES_H_ - -#include <glusterfs/glfs-message-id.h> - -/* To add new message IDs, append new identifiers at the end of the list. - * - * Never remove a message ID. If it's not used anymore, you can rename it or - * leave it as it is, but not delete it. This is to prevent reutilization of - * IDs by other messages. - * - * The component name must match one of the entries defined in - * glfs-message-id.h. - */ - -GLFS_MSGID(JBR, J_MSG_INIT_FAIL, J_MSG_RETRY_MSG, J_MSG_MEM_ERR, J_MSG_DICT_FLR, -           J_MSG_GENERIC, J_MSG_INVALID, J_MSG_NO_DATA, J_MSG_SYS_CALL_FAILURE, -           J_MSG_QUORUM_NOT_MET, J_MSG_LOCK_FAILURE); - -#endif /* _JBR_MESSAGES_H_ */ diff --git a/xlators/experimental/jbr-client/src/jbrc.c b/xlators/experimental/jbr-client/src/jbrc.c deleted file mode 100644 index 5c58a1efa99..00000000000 --- a/xlators/experimental/jbr-client/src/jbrc.c +++ /dev/null @@ -1,311 +0,0 @@ -/* -  Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com> - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <glusterfs/call-stub.h> -#include <glusterfs/defaults.h> -#include <glusterfs/timer.h> -#include <glusterfs/xlator.h> -#include "jbr-messages.h" -#include "jbrc.h" -#include <glusterfs/statedump.h> - -#define SCAR_LIMIT 20 -#define HILITE(x) ("[1;33m" x "[0m") - -/* - * The fops are actually generated by gen-fops.py; the rest was mostly copied - * from defaults.c (commit cd253754 on 27 August 2013). - */ - -enum gf_dht_mem_types_ { -    gf_mt_jbrc_private_t = gf_common_mt_end + 1, -    gf_mt_jbrc_end -}; - -char *JBRC_XATTR = "user.jbr.active"; - -static inline xlator_t * -ACTIVE_CHILD(xlator_t *parent) -{ -    jbrc_private_t *priv = parent->private; - -    return priv ? priv->active : FIRST_CHILD(parent); -} - -xlator_t * -next_xlator(xlator_t *this, xlator_t *prev) -{ -    xlator_list_t *trav; - -    for (trav = this->children; trav; trav = trav->next) { -        if (trav->xlator == prev) { -            return trav->next ? trav->next->xlator : this->children->xlator; -        } -    } - -    return NULL; -} - -void -jbrc_retry_cb(void *cb_arg) -{ -    jbrc_local_t *local = cb_arg; - -    gf_msg(__func__, GF_LOG_INFO, 0, J_MSG_RETRY_MSG, HILITE("retrying %p"), -           local); -    call_resume_wind(local->stub); -} - -#pragma generate - -int32_t -jbrc_forget(xlator_t *this, inode_t *inode) -{ -    gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, J_MSG_INIT_FAIL, -                     "xlator does not implement forget_cbk"); -    return 0; -} - -int32_t -jbrc_releasedir(xlator_t *this, fd_t *fd) -{ -    gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, J_MSG_INIT_FAIL, -                     "xlator does not implement releasedir_cbk"); -    return 0; -} - -int32_t -jbrc_release(xlator_t *this, fd_t *fd) -{ -    gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, J_MSG_INIT_FAIL, -                     "xlator does not implement release_cbk"); -    return 0; -} - -struct xlator_fops fops = { -    .lookup = jbrc_lookup, -    .stat = jbrc_stat, -    .fstat = jbrc_fstat, -    .truncate = jbrc_truncate, -    .ftruncate = jbrc_ftruncate, -    .access = jbrc_access, -    .readlink = jbrc_readlink, -    .mknod = jbrc_mknod, -    .mkdir = jbrc_mkdir, -    .unlink = jbrc_unlink, -    .rmdir = jbrc_rmdir, -    .symlink = jbrc_symlink, -    .rename = jbrc_rename, -    .link = jbrc_link, -    .create = jbrc_create, -    .open = jbrc_open, -    .readv = jbrc_readv, -    .writev = jbrc_writev, -    .flush = jbrc_flush, -    .fsync = jbrc_fsync, -    .opendir = jbrc_opendir, -    .readdir = jbrc_readdir, -    .readdirp = jbrc_readdirp, -    .fsyncdir = jbrc_fsyncdir, -    .statfs = jbrc_statfs, -    .setxattr = jbrc_setxattr, -    .getxattr = jbrc_getxattr, -    .fsetxattr = jbrc_fsetxattr, -    .fgetxattr = jbrc_fgetxattr, -    .removexattr = jbrc_removexattr, -    .fremovexattr = jbrc_fremovexattr, -    .lk = jbrc_lk, -    .inodelk = jbrc_inodelk, -    .finodelk = jbrc_finodelk, -    .entrylk = jbrc_entrylk, -    .fentrylk = jbrc_fentrylk, -    .rchecksum = jbrc_rchecksum, -    .xattrop = jbrc_xattrop, -    .fxattrop = jbrc_fxattrop, -    .setattr = jbrc_setattr, -    .fsetattr = jbrc_fsetattr, -    .fallocate = jbrc_fallocate, -    .discard = jbrc_discard, -}; - -struct xlator_cbks cbks = {}; - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    GF_VALIDATE_OR_GOTO("jbrc", this, out); - -    ret = xlator_mem_acct_init(this, gf_mt_jbrc_end + 1); - -    if (ret != 0) { -        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, J_MSG_MEM_ERR, -               "Memory accounting init failed"); -        return ret; -    } -out: -    return ret; -} - -int32_t -jbrc_init(xlator_t *this) -{ -    jbrc_private_t *priv = NULL; -    xlator_list_t *trav = NULL; - -    this->local_pool = mem_pool_new(jbrc_local_t, 128); -    if (!this->local_pool) { -        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, J_MSG_MEM_ERR, -               "failed to create jbrc_local_t pool"); -        goto err; -    } - -    priv = GF_CALLOC(1, sizeof(*priv), gf_mt_jbrc_private_t); -    if (!priv) { -        goto err; -    } - -    for (trav = this->children; trav; trav = trav->next) { -        ++(priv->n_children); -    } - -    priv->active = FIRST_CHILD(this); -    this->private = priv; -    return 0; - -err: -    if (priv) { -        GF_FREE(priv); -    } -    return -1; -} - -void -jbrc_fini(xlator_t *this) -{ -    GF_FREE(this->private); -} - -int -jbrc_get_child_index(xlator_t *this, xlator_t *kid) -{ -    xlator_list_t *trav; -    int retval = -1; - -    for (trav = this->children; trav; trav = trav->next) { -        ++retval; -        if (trav->xlator == kid) { -            return retval; -        } -    } - -    return -1; -} - -uint8_t -jbrc_count_up_kids(jbrc_private_t *priv) -{ -    uint8_t retval = 0; -    uint8_t i; - -    for (i = 0; i < priv->n_children; ++i) { -        if (priv->kid_state & (1 << i)) { -            ++retval; -        } -    } - -    return retval; -} - -int32_t -jbrc_notify(xlator_t *this, int32_t event, void *data, ...) -{ -    int32_t ret = 0; -    int32_t index = 0; -    jbrc_private_t *priv = NULL; - -    GF_VALIDATE_OR_GOTO(THIS->name, this, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); - -    switch (event) { -        case GF_EVENT_CHILD_UP: -            index = jbrc_get_child_index(this, data); -            if (index >= 0) { -                priv->kid_state |= (1 << index); -                priv->up_children = jbrc_count_up_kids(priv); -                gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                       "got CHILD_UP for %s, now %u kids", -                       ((xlator_t *)data)->name, priv->up_children); -            } -            ret = default_notify(this, event, data); -            break; -        case GF_EVENT_CHILD_DOWN: -            index = jbrc_get_child_index(this, data); -            if (index >= 0) { -                priv->kid_state &= ~(1 << index); -                priv->up_children = jbrc_count_up_kids(priv); -                gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                       "got CHILD_DOWN for %s, now %u kids", -                       ((xlator_t *)data)->name, priv->up_children); -            } -            break; -        default: -            ret = default_notify(this, event, data); -    } - -out: -    return ret; -} - -int -jbrc_priv_dump(xlator_t *this) -{ -    jbrc_private_t *priv = NULL; -    char key_prefix[GF_DUMP_MAX_BUF_LEN]; -    xlator_list_t *trav = NULL; -    int32_t i = -1; - -    GF_VALIDATE_OR_GOTO(THIS->name, this, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); - -    snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name); -    gf_proc_dump_add_section("%s", key_prefix); - -    gf_proc_dump_write("up_children", "%u", priv->up_children); - -    for (trav = this->children, i = 0; trav; trav = trav->next, i++) { -        snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "child_%d", i); -        gf_proc_dump_write(key_prefix, "%s", trav->xlator->name); -    } - -out: -    return 0; -} - -struct xlator_dumpops dumpops = { -    .priv = jbrc_priv_dump, -}; - -class_methods_t class_methods = { -    .init = jbrc_init, -    .fini = jbrc_fini, -    .notify = jbrc_notify, -}; - -struct volume_options options[] = { -    {.key = {NULL}}, -}; diff --git a/xlators/experimental/jbr-client/src/jbrc.h b/xlators/experimental/jbr-client/src/jbrc.h deleted file mode 100644 index f99178402b3..00000000000 --- a/xlators/experimental/jbr-client/src/jbrc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _JBRC_H_ -#define _JBRC_H_ - -typedef struct { -    xlator_t *active; -    uint8_t up_children; -    uint8_t n_children; -    uint32_t kid_state; -} jbrc_private_t; - -typedef struct { -    call_stub_t *stub; -    xlator_t *curr_xl; -    uint16_t scars; -} jbrc_local_t; - -#endif /* _JBRC_H_ */ diff --git a/xlators/experimental/jbr-server/Makefile.am b/xlators/experimental/jbr-server/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/jbr-server/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/jbr-server/src/Makefile.am b/xlators/experimental/jbr-server/src/Makefile.am deleted file mode 100644 index 42d3c8a6c36..00000000000 --- a/xlators/experimental/jbr-server/src/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -if WITH_SERVER -xlator_LTLIBRARIES = jbr.la -endif -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental - -nodist_jbr_la_SOURCES = jbr-cg.c -CLEANFILES = $(nodist_jbr_la_SOURCES) - -jbr_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -jbr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ -		$(top_builddir)/api/src/libgfapi.la - -noinst_HEADERS = jbr-internal.h \ -	$(top_srcdir)/xlators/lib/src/libxlator.h \ -	$(top_srcdir)/xlators/experimental/fdl/src/fdl.h \ -	$(top_srcdir)/glusterfsd/src/glusterfsd.h - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -	-I$(top_srcdir)/xlators/lib/src -I$(top_srcdir)/rpc/rpc-lib/src \ -	-I$(top_srcdir)/xlators/experimental/fdl/src/ \ -	-DSBIN_DIR=\"$(sbindir)\" -I$(top_srcdir)/api/src \ -	-DJBR_SCRIPT_PREFIX=\"$(jbrdir)\" \ -	-I$(top_srcdir)/xlators/experimental/jbr-client/src/ - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -JBR_PREFIX	= $(top_srcdir)/xlators/experimental/jbr-server/src -JBR_GEN_FOPS	= $(JBR_PREFIX)/gen-fops.py -JBR_TEMPLATES	= $(JBR_PREFIX)/all-templates.c.in -JBR_WRAPPER	= $(JBR_PREFIX)/jbr.c -noinst_PYTHON	= $(JBR_GEN_FOPS) -EXTRA_DIST	= $(JBR_TEMPLATES) $(JBR_WRAPPER) - -jbr-cg.c: $(JBR_GEN_FOPS) $(JBR_TEMPLATES) $(JBR_WRAPPER) -	$(PYTHON) $(JBR_GEN_FOPS) $(JBR_TEMPLATES) $(JBR_WRAPPER) > $@ - -uninstall-local: -	rm -f $(DESTDIR)$(xlatordir)/jbr.so diff --git a/xlators/experimental/jbr-server/src/all-templates.c.in b/xlators/experimental/jbr-server/src/all-templates.c.in deleted file mode 100644 index a9d57fc646f..00000000000 --- a/xlators/experimental/jbr-server/src/all-templates.c.in +++ /dev/null @@ -1,501 +0,0 @@ -/* - * You can put anything here - it doesn't even have to be a comment - and it - * will be ignored until we reach the first template-name comment. - */ - -/* template-name read-fop */ -int32_t jbr_@NAME@(call_frame_t *frame, xlator_t *this, @LONG_ARGS@) -{ -    jbr_private_t *priv = NULL; -    gf_boolean_t in_recon = _gf_false; -    int32_t op_errno = 0; -    int32_t recon_term, recon_index; - -    GF_VALIDATE_OR_GOTO("jbr", this, err); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, err); -    GF_VALIDATE_OR_GOTO(this->name, frame, err); - -    op_errno = EREMOTE; - -    /* allow reads during reconciliation       * -     * TBD: allow "dirty" reads on non-leaders * -     */ -    if (xdata && (dict_get_int32(xdata, RECON_TERM_XATTR, &recon_term) == 0) && -        (dict_get_int32(xdata, RECON_INDEX_XATTR, &recon_index) == 0)) { -        in_recon = _gf_true; -    } - -    if ((!priv->leader) && (in_recon == _gf_false)) { -        goto err; -    } - -    STACK_WIND(frame, default_@NAME@_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); -    return 0; - -err: -    STACK_UNWIND_STRICT(@NAME@, frame, -1, op_errno, @ERROR_ARGS@); -    return 0; -} - -/* template-name read-perform_local_op */ -/* No "perform_local_op" function needed for @NAME@ */ - -/* template-name read-dispatch */ -/* No "dispatch" function needed for @NAME@ */ - -/* template-name read-call_dispatch */ -/* No "call_dispatch" function needed for @NAME@ */ - -/* template-name read-fan-in */ -/* No "fan-in" function needed for @NAME@ */ - -/* template-name read-continue */ -/* No "continue" function needed for @NAME@ */ - -/* template-name read-complete */ -/* No "complete" function needed for @NAME@ */ - -/* template-name write-fop */ -int32_t jbr_@NAME@(call_frame_t *frame, xlator_t *this, @LONG_ARGS@) -{ -    jbr_local_t *local = NULL; -    jbr_private_t *priv = NULL; -    int32_t ret = -1; -    int op_errno = ENOMEM; - -    GF_VALIDATE_OR_GOTO("jbr", this, err); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, err); -    GF_VALIDATE_OR_GOTO(this->name, frame, err); - -#if defined(JBR_CG_NEED_FD) -    ret = jbr_leader_checks_and_init(frame, this, &op_errno, xdata, fd); -#else -    ret = jbr_leader_checks_and_init(frame, this, &op_errno, xdata, NULL); -#endif -    if (ret) -        goto err; - -    local = frame->local; - -    /* -     * If we let it through despite not being the leader, then we just want -     * to pass it on down without all of the additional xattrs, queuing, and -     * so on.  However, jbr_*_complete does depend on the initialization -     * immediately above this. -     */ -    if (!priv->leader) { -        STACK_WIND(frame, jbr_@NAME@_complete, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); -        return 0; -    } - -    ret = jbr_initialize_xdata_set_attrs(this, &xdata); -    if (ret) -        goto err; - -    local->xdata = dict_ref(xdata); -    local->stub = fop_@NAME@_stub(frame, jbr_@NAME@_continue, @SHORT_ARGS@); -    if (!local->stub) { -        goto err; -    } - -    /* -     * Can be used to just call_dispatch or be customised per fop to * -     * perform ops specific to that particular fop.                  * -     */ -    ret = jbr_@NAME@_perform_local_op(frame, this, &op_errno, @SHORT_ARGS@); -    if (ret) -        goto err; - -    return ret; -err: -    if (local) { -        if (local->stub) { -            call_stub_destroy(local->stub); -        } -        if (local->qstub) { -            call_stub_destroy(local->qstub); -        } -        if (local->fd) { -            fd_unref(local->fd); -        } -        mem_put(local); -    } -    STACK_UNWIND_STRICT(@NAME@, frame, -1, op_errno, @ERROR_ARGS@); -    return 0; -} - -/* template-name write-perform_local_op */ -int32_t jbr_@NAME@_perform_local_op(call_frame_t *frame, xlator_t *this, -                                    int *op_errno, @LONG_ARGS@) -{ -    int32_t ret = -1; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    GF_VALIDATE_OR_GOTO(this->name, op_errno, out); - -    ret = jbr_@NAME@_call_dispatch(frame, this, op_errno, @SHORT_ARGS@); - -out: -    return ret; -} - -/* template-name write-call_dispatch */ -int32_t jbr_@NAME@_call_dispatch(call_frame_t *frame, xlator_t *this, -                                 int *op_errno, @LONG_ARGS@) -{ -    jbr_local_t *local = NULL; -    jbr_private_t *priv = NULL; -    int32_t ret = -1; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, out); -    GF_VALIDATE_OR_GOTO(this->name, op_errno, out); - -#if defined(JBR_CG_QUEUE) -    jbr_inode_ctx_t *ictx = jbr_get_inode_ctx(this, fd->inode); -    if (!ictx) { -        *op_errno = EIO; -        goto out; -    } - -    LOCK(&ictx->lock); -    if (ictx->active) { -        gf_msg_debug(this->name, 0, "queuing request due to conflict"); -        /* -         * TBD: enqueue only for real conflict -         * -         * Currently we just act like all writes are in -         * conflict with one another.  What we should really do -         * is check the active/pending queues and defer only if -         * there's a conflict there. -         * -         * It's important to check the pending queue because we -         * might have an active request X which conflicts with -         * a pending request Y, and this request Z might -         * conflict with Y but not X.  If we checked only the -         * active queue then Z could jump ahead of Y, which -         * would be incorrect. -         */ -        local->qstub = fop_@NAME@_stub(frame, jbr_@NAME@_dispatch, -                                       @SHORT_ARGS@); -        if (!local->qstub) { -            UNLOCK(&ictx->lock); -            goto out; -        } -        list_add_tail(&local->qlinks, &ictx->pqueue); -        ++(ictx->pending); -        UNLOCK(&ictx->lock); -        ret = 0; -        goto out; -    } else { -        list_add_tail(&local->qlinks, &ictx->aqueue); -        ++(ictx->active); -    } -    UNLOCK(&ictx->lock); -#endif -    ret = jbr_@NAME@_dispatch(frame, this, @SHORT_ARGS@); - -out: -    return ret; -} - -/* template-name write-dispatch */ -int32_t jbr_@NAME@_dispatch(call_frame_t *frame, xlator_t *this, @LONG_ARGS@) -{ -    jbr_local_t *local = NULL; -    jbr_private_t *priv = NULL; -    int32_t ret = -1; -    xlator_list_t *trav; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, out); - -    /* -     * TBD: unblock pending request(s) if we fail after this point but -     * before we get to jbr_@NAME@_complete (where that code currently -     * resides). -     */ - -    local->call_count = priv->n_children - 1; -    for (trav = this->children->next; trav; trav = trav->next) { -        STACK_WIND(frame, jbr_@NAME@_fan_in, trav->xlator, -                   trav->xlator->fops->@NAME@, @SHORT_ARGS@); -    } - -    /* TBD: variable Issue count */ -    ret = 0; -out: -    return ret; -} - -/* template-name write-fan-in */ -int32_t jbr_@NAME@_fan_in(call_frame_t *frame, void *cookie, xlator_t *this, -                            int32_t op_ret, int32_t op_errno, @LONG_ARGS@) -{ -    jbr_local_t *local = NULL; -    int32_t ret = -1; -    uint8_t call_count; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, out); - -    gf_msg_trace(this->name, 0, "op_ret = %d, op_errno = %d\n", op_ret, -                 op_errno); - -    LOCK(&frame->lock); -    call_count = --(local->call_count); -    if (op_ret != -1) { -        /* Increment the number of successful acks * -         * received for the operation.             * -         */ -        (local->successful_acks)++; -        local->successful_op_ret = op_ret; -    } -    gf_msg_debug(this->name, 0, "succ_acks = %d, op_ret = %d, op_errno = %d\n", -                 op_ret, op_errno, local->successful_acks); -    UNLOCK(&frame->lock); - -    /* TBD: variable Completion count */ -    if (call_count == 0) { -        call_resume(local->stub); -    } - -    ret = 0; -out: -    return ret; -} - -/* template-name write-continue */ -int32_t jbr_@NAME@_continue(call_frame_t *frame, xlator_t *this, @LONG_ARGS@) -{ -    int32_t ret = -1; -    gf_boolean_t result = _gf_false; -    jbr_local_t *local = NULL; -    jbr_local_t *new_local = NULL; -    jbr_private_t *priv = NULL; -    int32_t op_errno = 0; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    priv = this->private; -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); -    GF_VALIDATE_OR_GOTO(this->name, local, out); - -    /* Perform quorum check to see if the leader needs     * -     * to perform the operation. If the operation will not * -     * meet quorum irrespective of the leader's result     * -     * there is no point in the leader performing the fop  * -     */ -    result = fop_quorum_check(this, (double)priv->n_children, -                              (double)local->successful_acks + 1); -    if (result == _gf_false) { -        gf_msg(this->name, GF_LOG_ERROR, EROFS, J_MSG_QUORUM_NOT_MET, -               "Didn't receive enough acks " -               "to meet quorum. Failing the operation without trying " -               "it on the leader."); - -#if defined(JBR_CG_QUEUE) -        /* -         * In case of a fop failure, before unwinding need to * -         * remove it from queue                               * -         */ -        ret = jbr_remove_from_queue(frame, this); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_GENERIC, -                   "Failed to remove from queue."); -        } -#endif - -        /* -         * In this case, the quorum is not met on the followers  * -         * So the operation will not be performed on the leader  * -         * and a rollback will be sent via GF_FOP_IPC to all the * -         * followers, where this particular fop's term and index * -         * numbers will be journaled, and later used to rollback * -         */ -        call_frame_t *new_frame; - -        new_frame = copy_frame(frame); - -        if (new_frame) { -            new_local = mem_get0(this->local_pool); -            if (new_local) { -                INIT_LIST_HEAD(&new_local->qlinks); -                ret = dict_set_int32(local->xdata, "rollback-fop", -                                     GF_FOP_@UPNAME@); -                if (ret) { -                    gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -                           "failed to set rollback-fop"); -                } else { -                    new_local->xdata = dict_ref(local->xdata); -                    new_frame->local = new_local; -                    jbr_ipc_call_dispatch(new_frame, this, &op_errno, -                                          FDL_IPC_JBR_SERVER_ROLLBACK, -                                          new_local->xdata); -                } -            } else { -                gf_log(this->name, GF_LOG_WARNING, -                       "Could not create local for new_frame"); -            } -        } else { -            gf_log(this->name, GF_LOG_WARNING, "Could not send rollback ipc"); -        } - -        STACK_UNWIND_STRICT(@NAME@, frame, -1, EROFS, @ERROR_ARGS@); -    } else { -        STACK_WIND(frame, jbr_@NAME@_complete, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); -    } - -out: -    return 0; -} - -/* template-name write-complete */ -int32_t jbr_@NAME@_complete(call_frame_t *frame, void *cookie, xlator_t *this, -                              int32_t op_ret, int32_t op_errno, @LONG_ARGS@) -{ -    int32_t ret = -1; -    gf_boolean_t result = _gf_false; -    jbr_private_t *priv = NULL; -    jbr_local_t *local = NULL; -    jbr_local_t *new_local = NULL; - -    GF_VALIDATE_OR_GOTO("jbr", this, err); -    GF_VALIDATE_OR_GOTO(this->name, frame, err); -    priv = this->private; -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, priv, err); -    GF_VALIDATE_OR_GOTO(this->name, local, err); - -    /* If the fop failed on the leader, then reduce one successful ack -     * before calculating the fop quorum -     */ -    LOCK(&frame->lock); -    if (op_ret == -1) -        (local->successful_acks)--; -    UNLOCK(&frame->lock); - -#if defined(JBR_CG_QUEUE) -    ret = jbr_remove_from_queue(frame, this); -    if (ret) -        goto err; -#endif - -#if defined(JBR_CG_FSYNC) -    jbr_mark_fd_dirty(this, local); -#endif - -#if defined(JBR_CG_NEED_FD) -    fd_unref(local->fd); -#endif - -    /* After the leader completes the fop, a quorum check is      * -     * performed, taking into account the outcome of the fop      * -     * on the leader. Irrespective of the fop being successful    * -     * or failing on the leader, the result of the quorum will    * -     * determine if the overall fop is successful or not. For     * -     * example, a fop might have succeeded on every node except   * -     * the leader, in which case as quorum is being met, the fop  * -     * will be treated as a successful fop, even though it failed * -     * on the leader. On follower nodes, no quorum check should   * -     * be done, and the result is returned to the leader as is.   * -     */ -    if (priv->leader) { -        result = fop_quorum_check(this, (double)priv->n_children, -                                  (double)local->successful_acks + 1); -        if (result == _gf_false) { -            op_ret = -1; -            op_errno = EROFS; -            gf_msg(this->name, GF_LOG_ERROR, EROFS, J_MSG_QUORUM_NOT_MET, -                   "Quorum is not met. " -                   "The operation has failed."); -            /* -             * In this case, the quorum is not met after the      * -             * operation is performed on the leader. Hence a      * -             * rollback will be sent via GF_FOP_IPC to the leader * -             * where this particular fop's term and index numbers * -             * will be journaled, and later used to rollback.     * -             * The same will be done on all the followers         * -             */ -            call_frame_t *new_frame; - -            new_frame = copy_frame(frame); -            if (new_frame) { -                new_local = mem_get0(this->local_pool); -                if (new_local) { -                    INIT_LIST_HEAD(&new_local->qlinks); -                    gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -                           "op = %d", new_frame->op); -                    ret = dict_set_int32(local->xdata, "rollback-fop", -                                         GF_FOP_@UPNAME@); -                    if (ret) { -                        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -                               "failed to set " -                               "rollback-fop"); -                    } else { -                        new_local->xdata = dict_ref(local->xdata); -                        new_frame->local = new_local; -                        /* -                         * Calling STACK_WIND instead * -                         * of jbr_ipc as it will not  * -                         * unwind to the previous     * -                         * translators like it will   * -                         * in case of jbr_ipc.        * -                         */ -                        STACK_WIND( -                            new_frame, jbr_ipc_complete, FIRST_CHILD(this), -                            FIRST_CHILD(this)->fops->ipc, -                            FDL_IPC_JBR_SERVER_ROLLBACK, new_local->xdata); -                    } -                } else { -                    gf_log(this->name, GF_LOG_WARNING, -                           "Could not create local " -                           "for new_frame"); -                } -            } else { -                gf_log(this->name, GF_LOG_WARNING, -                       "Could not send rollback ipc"); -            } -        } else { -#if defined(JBR_CG_NEED_FD) -            op_ret = local->successful_op_ret; -#else -            op_ret = 0; -#endif -            op_errno = 0; -            gf_msg_debug(this->name, 0, -                         "Quorum has met. The operation has succeeded."); -        } -    } - -    /* -     * Unrefing the reference taken in jbr_@NAME@ () * -     */ -    dict_unref(local->xdata); - -    STACK_UNWIND_STRICT(@NAME@, frame, op_ret, op_errno, @SHORT_ARGS@); - -    return 0; - -err: -    STACK_UNWIND_STRICT(@NAME@, frame, -1, 0, @SHORT_ARGS@); - -    return 0; -} diff --git a/xlators/experimental/jbr-server/src/gen-fops.py b/xlators/experimental/jbr-server/src/gen-fops.py deleted file mode 100755 index 616782bba45..00000000000 --- a/xlators/experimental/jbr-server/src/gen-fops.py +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/python3 - -# This script generates the boilerplate versions of most fops and cbks in the -# server.  This allows the details of leadership-status checking, sequencing -# between leader and followers (including fan-out), and basic error checking -# to be centralized one place, with per-operation code kept to a minimum. - -from __future__ import print_function -import os -import re -import string -import sys - -curdir = os.path.dirname(sys.argv[0]) -gendir = os.path.join(curdir, '../../../../libglusterfs/src') -sys.path.append(gendir) -from generator import ops, fop_subs, cbk_subs, generate - -# We really want the callback argument list, even when we're generating fop -# code, so we propagate here. -# TBD: this should probably be right in generate.py -for k, v in cbk_subs.items(): -	fop_subs[k]['@ERROR_ARGS@'] = v['@ERROR_ARGS@'] - -# Stolen from old codegen.py -def load_templates (path): -	templates = {} -	tmpl_re = re.compile("/\* template-name (.*) \*/") -	templates = {} -	t_name = None -	for line in open(path, "r").readlines(): -		if not line: -			break -		m = tmpl_re.match(line) -		if m: -			if t_name: -				templates[t_name] = ''.join(t_contents) -			t_name = m.group(1).strip() -			t_contents = [] -		elif t_name: -			t_contents.append(line) -	if t_name: -		templates[t_name] = ''.join(t_contents) -	return templates - -# We need two types of templates.  The first, for pure read operations, just -# needs to do a simple am-i-leader check (augmented to allow dirty reads). -# The second, for pure writes, needs to do fan-out to followers between those -# initial checks and local execution.  There are other operations that don't -# fit neatly into either category - e.g. lock ops or fsync - so we'll just have -# to handle those manually.  The table thus includes entries only for those we -# can categorize.  The special cases, plus any new operations we've never even -# heard of, aren't in there. -# -# Various keywords can be used to define/undefine preprocessor symbols used -# in the templates, on a per-function basis.  For example, if the keyword here -# is "fsync" (lowercase word or abbreviation) that will cause JBR_CG_FSYNC -# (prefix plus uppercase version) to be defined above all of the generated code -# for that fop. - -fop_table = { -	"access":		"read", -	"create":		"write", -	"discard":		"write", -#	"entrylk":		"read", -	"fallocate":	"write", -#	"fentrylk":		"read", -	"fgetxattr":	"read", -#	"finodelk":		"read", -#	"flush":		"read", -	"fremovexattr":	"write", -	"fsetattr":		"write", -	"fsetxattr":	"write", -	"fstat":		"read", -#	"fsync":		"read", -#	"fsyncdir":		"read", -	"ftruncate":	"write", -	"fxattrop":		"write", -	"getxattr":		"read", -#	"inodelk":		"read", -	"link":			"write", -	"lk":			"write,queue", -#	"lookup":		"read", -	"mkdir":		"write", -	"mknod":		"write", -	"open":			"write", -	"opendir":		"read", -	"rchecksum":	"read", -	"readdir":		"read", -	"readdirp":		"read", -	"readlink":		"read", -	"readv":		"read", -	"removexattr":	"write", -	"rename":		"write", -	"rmdir":		"write", -	"setattr":		"write", -	"setxattr":		"write", -	"stat":			"read", -	"statfs":		"read", -	"symlink":		"write", -	"truncate":		"write", -	"unlink":		"write", -	"writev":		"write,fsync,queue", -	"xattrop":		"write", -	"ipc":			"write", -} - -# Mention those fops in the selective_generate table, for which -# only a few common functions will be generated, and mention those -# functions. Rest of the functions can be customized -selective_generate = { -	"lk":			"fop,dispatch,call_dispatch", -	"ipc":			"dispatch,call_dispatch", -} - -# Stolen from gen_fdl.py -def gen_server (templates): -	fops_done = [] -	for name in fop_table.keys(): -		info = fop_table[name].split(",") -		kind = info[0] -		flags = info[1:] - -		# generate all functions for the fops in fop_table -		# except for the ones in selective_generate for which -		# generate only the functions mentioned in the -		# selective_generate table -		gen_funcs = "fop,complete,continue,fan-in,dispatch, \ -			call_dispatch,perform_local_op" -		if name in selective_generate: -			gen_funcs = selective_generate[name].split(",") - -		if ("fsync" in flags) or ("queue" in flags): -			flags.append("need_fd") -		for fname in flags: -			print("#define JBR_CG_%s" % fname.upper()) - -		if 'complete' in gen_funcs: -			print(generate(templates[kind+"-complete"], -					name, cbk_subs)) - -		if 'continue' in gen_funcs: -			print(generate(templates[kind+"-continue"], -					name, fop_subs)) - -		if 'fan-in' in gen_funcs: -			print(generate(templates[kind+"-fan-in"], -					name, cbk_subs)) - -		if 'dispatch' in gen_funcs: -			print(generate(templates[kind+"-dispatch"], -					name, fop_subs)) - -		if 'call_dispatch' in gen_funcs: -			print(generate(templates[kind+"-call_dispatch"], -					name, fop_subs)) - -		if 'perform_local_op' in gen_funcs: -			print(generate(templates[kind+"-perform_local_op"], -					name, fop_subs)) - -		if 'fop' in gen_funcs: -			print(generate(templates[kind+"-fop"], name, fop_subs)) - -		for fname in flags: -			print("#undef JBR_CG_%s" % fname.upper()) -		fops_done.append(name) -	# Just for fun, emit the fops table too. -	print("struct xlator_fops fops = {") -	for x in fops_done: -		print(("	.%s = jbr_%s,"%(x, x))) -	print("};") - -tmpl = load_templates(sys.argv[1]) -for l in open(sys.argv[2], 'r').readlines(): -	if l.find('#pragma generate') != -1: -		print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") -		gen_server(tmpl) -		print("/* END GENERATED CODE */") -	else: -		print(l[:-1]) diff --git a/xlators/experimental/jbr-server/src/jbr-internal.h b/xlators/experimental/jbr-server/src/jbr-internal.h deleted file mode 100644 index f225e988a5f..00000000000 --- a/xlators/experimental/jbr-server/src/jbr-internal.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -   Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#include <sys/stat.h> -#include <sys/types.h> - -#define LEADER_XATTR "user.jbr.leader" -#define SECOND_CHILD(xl) (xl->children->next->xlator) -#define RECONCILER_PATH JBR_SCRIPT_PREFIX "/reconciler.py" -#define CHANGELOG_ENTRY_SIZE 128 - -enum { -    gf_mt_jbr_private_t = gf_common_mt_end + 1, -    gf_mt_jbr_fd_ctx_t, -    gf_mt_jbr_inode_ctx_t, -    gf_mt_jbr_dirty_t, -    gf_mt_jbr_end -}; - -typedef enum jbr_recon_notify_ev_id_t { -    JBR_RECON_SET_LEADER = 1, -    JBR_RECON_ADD_CHILD = 2 -} jbr_recon_notify_ev_id_t; - -typedef struct _jbr_recon_notify_ev_s { -    jbr_recon_notify_ev_id_t id; -    uint32_t index; /* in case of add */ -    struct list_head list; -} jbr_recon_notify_ev_t; - -typedef struct { -    /* -     * This is a hack to allow a non-leader to accept requests while the -     * leader is down, and it only works for n=2.  The way it works is that -     * "config_leader" indicates the state from our options (via init or -     * reconfigure) but "leader" is what the fop code actually looks at.  If -     * config_leader is true, then leader will *always* be true as well, -     * giving that brick precedence.  If config_leader is false, then -     * leader will only be true if there is no connection to the other -     * brick (tracked in jbr_notify). -     * -     * TBD: implement real leader election -     */ -    gf_boolean_t config_leader; -    gf_boolean_t leader; -    uint8_t up_children; -    uint8_t n_children; -    char *vol_file; -    uint32_t current_term; -    uint32_t kid_state; -    gf_lock_t dirty_lock; -    struct list_head dirty_fds; -    uint32_t index; -    gf_lock_t index_lock; -    double quorum_pct; -    int term_fd; -    long term_total; -    long term_read; -    /* -     * This is a super-duper hack, but it will do for now.  The reason it's -     * a hack is that we pass this to dict_set_static_bin, so we don't have -     * to mess around with allocating and freeing it on every single IPC -     * request, but it's totally not thread-safe.  On the other hand, there -     * should only be one reconciliation thread running and calling these -     * functions at a time, so maybe that doesn't matter. -     * -     * TBD: re-evaluate how to manage this -     */ -    char term_buf[CHANGELOG_ENTRY_SIZE]; -    gf_boolean_t child_up; /* To maintain the state of * -                            * the translator */ -} jbr_private_t; - -typedef struct { -    call_stub_t *stub; -    call_stub_t *qstub; -    uint32_t call_count; -    uint32_t successful_acks; -    uint32_t successful_op_ret; -    fd_t *fd; -    struct list_head qlinks; -    dict_t *xdata; -} jbr_local_t; - -/* - * This should match whatever changelog returns on the pre-op for us to pass - * when we're ready for our post-op. - */ -typedef uint32_t log_id_t; - -typedef struct { -    struct list_head links; -    log_id_t id; -} jbr_dirty_list_t; - -typedef struct { -    fd_t *fd; -    struct list_head dirty_list; -    struct list_head fd_list; -} jbr_fd_ctx_t; - -typedef struct { -    gf_lock_t lock; -    uint32_t active; -    struct list_head aqueue; -    uint32_t pending; -    struct list_head pqueue; -} jbr_inode_ctx_t; - -void -jbr_start_reconciler(xlator_t *this); diff --git a/xlators/experimental/jbr-server/src/jbr.c b/xlators/experimental/jbr-server/src/jbr.c deleted file mode 100644 index f5fb55fee18..00000000000 --- a/xlators/experimental/jbr-server/src/jbr.c +++ /dev/null @@ -1,1676 +0,0 @@ -/* -   Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <fnmatch.h> -#include <glusterfs/call-stub.h> -#include <glusterfs/defaults.h> -#include <glusterfs/xlator.h> -#include "glfs.h" -#include "glfs-internal.h" -#include <glusterfs/run.h> -#include <glusterfs/common-utils.h> -#include <glusterfs/syncop.h> -#include <glusterfs/syscall.h> -#include <glusterfs/compat-errno.h> -#include "fdl.h" - -#include "jbr-internal.h" -#include "jbr-messages.h" - -#define JBR_FLUSH_INTERVAL 5 - -enum { -    /* echo "cluster/jbr-server" | md5sum | cut -c 1-8 */ -    JBR_SERVER_IPC_BASE = 0x0e2d66a5, -    JBR_SERVER_TERM_RANGE, -    JBR_SERVER_OPEN_TERM, -    JBR_SERVER_NEXT_ENTRY -}; - -/* - * Need to declare jbr_lk_call_dispatch as jbr_lk_continue and * - * jbr_lk_perform_local_op call it, before code is generated.  * - */ -int32_t -jbr_lk_call_dispatch(call_frame_t *frame, xlator_t *this, int *op_errno, -                     fd_t *fd, int32_t cmd, struct gf_flock *lock, -                     dict_t *xdata); - -int32_t -jbr_lk_dispatch(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, -                struct gf_flock *lock, dict_t *xdata); - -int32_t -jbr_ipc_call_dispatch(call_frame_t *frame, xlator_t *this, int *op_errno, -                      int32_t op, dict_t *xdata); - -int32_t -jbr_ipc_complete(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, dict_t *xdata); - -/* Used to check the quorum of acks received after the fop - * confirming the status of the fop on all the brick processes - * for this particular subvolume - */ -gf_boolean_t -fop_quorum_check(xlator_t *this, double n_children, double current_state) -{ -    jbr_private_t *priv = NULL; -    gf_boolean_t result = _gf_false; -    double required = 0; -    double current = 0; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); - -    required = n_children * priv->quorum_pct; - -    /* -     * Before performing the fop on the leader, we need to check, -     * if there is any merit in performing the fop on the leader. -     * In a case, where even a successful write on the leader, will -     * not meet quorum, there is no point in trying the fop on the -     * leader. -     * When this function is called after the leader has tried -     * performing the fop, this check will calculate quorum taking into -     * account the status of the fop on the leader. If the leader's -     * op_ret was -1, the complete function would account that by -     * decrementing successful_acks by 1 -     */ - -    current = current_state * 100.0; - -    if (current < required) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_QUORUM_NOT_MET, -               "Quorum not met. quorum_pct = %f " -               "Current State = %f, Required State = %f", -               priv->quorum_pct, current, required); -    } else -        result = _gf_true; - -out: -    return result; -} - -jbr_inode_ctx_t * -jbr_get_inode_ctx(xlator_t *this, inode_t *inode) -{ -    uint64_t ctx_int = 0LL; -    jbr_inode_ctx_t *ctx_ptr; - -    if (__inode_ctx_get(inode, this, &ctx_int) == 0) { -        ctx_ptr = (jbr_inode_ctx_t *)(long)ctx_int; -    } else { -        ctx_ptr = GF_CALLOC(1, sizeof(*ctx_ptr), gf_mt_jbr_inode_ctx_t); -        if (ctx_ptr) { -            ctx_int = (uint64_t)(long)ctx_ptr; -            if (__inode_ctx_set(inode, this, &ctx_int) == 0) { -                LOCK_INIT(&ctx_ptr->lock); -                INIT_LIST_HEAD(&ctx_ptr->aqueue); -                INIT_LIST_HEAD(&ctx_ptr->pqueue); -            } else { -                GF_FREE(ctx_ptr); -                ctx_ptr = NULL; -            } -        } -    } - -    return ctx_ptr; -} - -jbr_fd_ctx_t * -jbr_get_fd_ctx(xlator_t *this, fd_t *fd) -{ -    uint64_t ctx_int = 0LL; -    jbr_fd_ctx_t *ctx_ptr; - -    if (__fd_ctx_get(fd, this, &ctx_int) == 0) { -        ctx_ptr = (jbr_fd_ctx_t *)(long)ctx_int; -    } else { -        ctx_ptr = GF_CALLOC(1, sizeof(*ctx_ptr), gf_mt_jbr_fd_ctx_t); -        if (ctx_ptr) { -            if (__fd_ctx_set(fd, this, (uint64_t)(uintptr_t)ctx_ptr) == 0) { -                INIT_LIST_HEAD(&ctx_ptr->dirty_list); -                INIT_LIST_HEAD(&ctx_ptr->fd_list); -            } else { -                GF_FREE(ctx_ptr); -                ctx_ptr = NULL; -            } -        } -    } - -    return ctx_ptr; -} - -void -jbr_mark_fd_dirty(xlator_t *this, jbr_local_t *local) -{ -    fd_t *fd = local->fd; -    jbr_fd_ctx_t *ctx_ptr; -    jbr_dirty_list_t *dirty; -    jbr_private_t *priv = this->private; - -    /* -     * TBD: don't do any of this for O_SYNC/O_DIRECT writes. -     * Unfortunately, that optimization requires that we distinguish -     * between writev and other "write" calls, saving the original flags -     * and checking them in the callback.  Too much work for too little -     * gain right now. -     */ - -    LOCK(&fd->lock); -    ctx_ptr = jbr_get_fd_ctx(this, fd); -    dirty = GF_CALLOC(1, sizeof(*dirty), gf_mt_jbr_dirty_t); -    if (ctx_ptr && dirty) { -        gf_msg_trace(this->name, 0, "marking fd %p as dirty (%p)", fd, dirty); -        /* TBD: fill dirty->id from what changelog gave us */ -        list_add_tail(&dirty->links, &ctx_ptr->dirty_list); -        if (list_empty(&ctx_ptr->fd_list)) { -            /* Add a ref so _release doesn't get called. */ -            ctx_ptr->fd = fd_ref(fd); -            LOCK(&priv->dirty_lock); -            list_add_tail(&ctx_ptr->fd_list, &priv->dirty_fds); -            UNLOCK(&priv->dirty_lock); -        } -    } else { -        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, J_MSG_MEM_ERR, -               "could not mark %p dirty", fd); -        if (ctx_ptr) { -            GF_FREE(ctx_ptr); -        } -        if (dirty) { -            GF_FREE(dirty); -        } -    } -    UNLOCK(&fd->lock); -} - -#define JBR_TERM_XATTR "trusted.jbr.term" -#define JBR_INDEX_XATTR "trusted.jbr.index" -#define JBR_REP_COUNT_XATTR "trusted.jbr.rep-count" -#define RECON_TERM_XATTR "trusted.jbr.recon-term" -#define RECON_INDEX_XATTR "trusted.jbr.recon-index" - -int32_t -jbr_leader_checks_and_init(call_frame_t *frame, xlator_t *this, int *op_errno, -                           dict_t *xdata, fd_t *fd) -{ -    jbr_local_t *local = NULL; -    jbr_private_t *priv = NULL; -    int32_t ret = -1; -    gf_boolean_t result = _gf_false; -    int from_leader = _gf_false; -    int from_recon = _gf_false; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); -    GF_VALIDATE_OR_GOTO(this->name, op_errno, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); - -    /* -     * Our first goal here is to avoid "split brain surprise" for users who -     * specify exactly 50% with two- or three-way replication.  That means -     * either a more-than check against half the total replicas or an -     * at-least check against half of our peers (one less).  Of the two, -     * only an at-least check supports the intuitive use of 100% to mean -     * all replicas must be present, because "more than 100%" will never -     * succeed regardless of which count we use.  This leaves us with a -     * slightly non-traditional definition of quorum ("at least X% of peers -     * not including ourselves") but one that's useful enough to be worth -     * it. -     * -     * Note that n_children and up_children *do* include the local -     * subvolume, so we need to subtract one in each case. -     */ -    if (priv->leader) { -        result = fop_quorum_check(this, (double)(priv->n_children - 1), -                                  (double)(priv->up_children - 1)); - -        if (result == _gf_false) { -            /* Emulate the AFR client-side-quorum behavior. */ -            gf_msg(this->name, GF_LOG_ERROR, EROFS, J_MSG_QUORUM_NOT_MET, -                   "Sufficient number of " -                   "subvolumes are not up to meet quorum."); -            *op_errno = EROFS; -            goto out; -        } -    } else { -        if (xdata) { -            from_leader = !!dict_get(xdata, JBR_TERM_XATTR); -            from_recon = !!dict_get(xdata, RECON_TERM_XATTR) && -                         !!dict_get(xdata, RECON_INDEX_XATTR); -        } else { -            from_leader = from_recon = _gf_false; -        } - -        /* follower/recon path        * -         * just send it to local node * -         */ -        if (!from_leader && !from_recon) { -            *op_errno = EREMOTE; -            goto out; -        } -    } - -    local = mem_get0(this->local_pool); -    if (!local) { -        goto out; -    } - -    if (fd) -        local->fd = fd_ref(fd); -    else -        local->fd = NULL; - -    INIT_LIST_HEAD(&local->qlinks); -    local->successful_acks = 0; -    frame->local = local; - -    ret = 0; -out: -    return ret; -} - -int32_t -jbr_initialize_xdata_set_attrs(xlator_t *this, dict_t **xdata) -{ -    jbr_private_t *priv = NULL; -    int32_t ret = -1; -    uint32_t ti = 0; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); -    GF_VALIDATE_OR_GOTO(this->name, xdata, out); - -    if (!*xdata) { -        *xdata = dict_new(); -        if (!*xdata) { -            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, J_MSG_MEM_ERR, -                   "failed to allocate xdata"); -            goto out; -        } -    } - -    if (dict_set_int32(*xdata, JBR_TERM_XATTR, priv->current_term) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -               "failed to set jbr-term"); -        goto out; -    } - -    LOCK(&priv->index_lock); -    ti = ++(priv->index); -    UNLOCK(&priv->index_lock); -    if (dict_set_int32(*xdata, JBR_INDEX_XATTR, ti) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -               "failed to set index"); -        goto out; -    } - -    ret = 0; -out: -    return ret; -} - -int32_t -jbr_remove_from_queue(call_frame_t *frame, xlator_t *this) -{ -    int32_t ret = -1; -    jbr_inode_ctx_t *ictx = NULL; -    jbr_local_t *local = NULL; -    jbr_local_t *next = NULL; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, out); - -    if (local->qlinks.next != &local->qlinks) { -        list_del(&local->qlinks); -        ictx = jbr_get_inode_ctx(this, local->fd->inode); -        if (ictx) { -            LOCK(&ictx->lock); -            if (ictx->pending) { -                /* -                 * TBD: dequeue *all* non-conflicting -                 * reqs -                 * -                 * With the stub implementation there -                 * can only be one request active at a -                 * time (zero here) so it's not an -                 * issue.  In a real implementation -                 * there might still be other active -                 * requests to check against, and -                 * multiple pending requests that could -                 * continue. -                 */ -                gf_msg_debug(this->name, 0, "unblocking next request"); -                --(ictx->pending); -                next = list_entry(ictx->pqueue.next, jbr_local_t, qlinks); -                list_del(&next->qlinks); -                list_add_tail(&next->qlinks, &ictx->aqueue); -                call_resume(next->qstub); -            } else { -                --(ictx->active); -            } -            UNLOCK(&ictx->lock); -        } -    } - -    ret = 0; - -out: -    return ret; -} - -int32_t -jbr_lk_complete(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, struct gf_flock *flock, -                dict_t *xdata) -{ -    int32_t ret = -1; -    jbr_private_t *priv = NULL; -    jbr_local_t *local = NULL; -    gf_boolean_t result = _gf_false; - -    GF_VALIDATE_OR_GOTO("jbr", this, err); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv, err); -    GF_VALIDATE_OR_GOTO(this->name, frame, err); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, err); -    GF_VALIDATE_OR_GOTO(this->name, flock, err); -    GF_VALIDATE_OR_GOTO(this->name, xdata, err); - -    /* -     * Remove from queue for unlock operation only   * -     * For lock operation, it will be done in fan-in * -     */ -    if (flock->l_type == F_UNLCK) { -        ret = jbr_remove_from_queue(frame, this); -        if (ret) -            goto err; -    } - -    /* -     * On a follower, unwind with the op_ret and op_errno. On a * -     * leader, if the fop is a locking fop, and its a failure,  * -     * send fail, else call stub which will dispatch the fop to * -     * the followers.                                           * -     *                                                          * -     * If the fop is a unlocking fop, check quorum. If quorum   * -     * is met, then send success. Else Rollback on leader,      * -     * followed by followers, and then send -ve ack to client.  * -     */ -    if (priv->leader) { -        /* Increase the successful acks if it's a success. */ -        LOCK(&frame->lock); -        if (op_ret != -1) -            (local->successful_acks)++; -        UNLOCK(&frame->lock); - -        if (flock->l_type == F_UNLCK) { -            result = fop_quorum_check(this, (double)priv->n_children, -                                      (double)local->successful_acks); -            if (result == _gf_false) { -                op_ret = -1; -                op_errno = EROFS; -                gf_msg(this->name, GF_LOG_ERROR, EROFS, J_MSG_QUORUM_NOT_MET, -                       "Quorum is not met. " -                       "The operation has failed."); - -                /* TODO: PERFORM UNLOCK ROLLBACK ON LEADER * -                 * FOLLOWED BY FOLLOWERS. */ -            } else { -                op_ret = 0; -                op_errno = 0; -            } - -            fd_unref(local->fd); -            STACK_UNWIND_STRICT(lk, frame, op_ret, op_errno, flock, xdata); -        } else { -            if (op_ret == -1) { -                gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_LOCK_FAILURE, -                       "The lock operation failed on " -                       "the leader."); - -                fd_unref(local->fd); -                STACK_UNWIND_STRICT(lk, frame, op_ret, op_errno, flock, xdata); -            } else { -                if (!local->stub) { -                    goto err; -                } - -                call_resume(local->stub); -            } -        } -    } else { -        fd_unref(local->fd); -        STACK_UNWIND_STRICT(lk, frame, op_ret, op_errno, flock, xdata); -    } - -    return 0; - -err: -    if (local) { -        if (local->stub) { -            call_stub_destroy(local->stub); -        } -        if (local->qstub) { -            call_stub_destroy(local->qstub); -        } -        if (local->fd) { -            fd_unref(local->fd); -        } -        mem_put(local); -    } -    STACK_UNWIND_STRICT(lk, frame, -1, op_errno, flock, xdata); -    return 0; -} - -int32_t -jbr_lk_fan_in(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct gf_flock *flock, dict_t *xdata) -{ -    uint8_t call_count = -1; -    int32_t ret = -1; -    gf_boolean_t result = _gf_false; -    jbr_local_t *local = NULL; -    jbr_private_t *priv = NULL; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    priv = this->private; -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); -    GF_VALIDATE_OR_GOTO(this->name, local, out); - -    gf_msg_trace(this->name, 0, "op_ret = %d, op_errno = %d\n", op_ret, -                 op_errno); - -    LOCK(&frame->lock); -    call_count = --(local->call_count); -    if (op_ret != -1) { -        /* Increment the number of successful acks * -         * received for the operation.             * -         */ -        (local->successful_acks)++; -        local->successful_op_ret = op_ret; -    } -    gf_msg_debug(this->name, 0, "succ_acks = %d, op_ret = %d, op_errno = %d\n", -                 op_ret, op_errno, local->successful_acks); -    UNLOCK(&frame->lock); - -    if (call_count == 0) { -        /* -         * If the fop is a locking fop, then check quorum. If quorum * -         * is met, send successful ack to the client. If quorum is   * -         * not met, then rollback locking on followers, followed by  * -         * rollback of locking on leader, and then sending -ve ack   * -         * to the client.                                            * -         *                                                           * -         * If the fop is a unlocking fop, then call stub.            * -         */ -        if (flock->l_type == F_UNLCK) { -            call_resume(local->stub); -        } else { -            /* -             * Remove from queue for locking fops, for unlocking * -             * fops, it is taken care of in jbr_lk_complete      * -             */ -            ret = jbr_remove_from_queue(frame, this); -            if (ret) -                goto out; - -            fd_unref(local->fd); - -            result = fop_quorum_check(this, (double)priv->n_children, -                                      (double)local->successful_acks); -            if (result == _gf_false) { -                gf_msg(this->name, GF_LOG_ERROR, EROFS, J_MSG_QUORUM_NOT_MET, -                       "Didn't receive enough acks to meet " -                       "quorum. Failing the locking " -                       "operation and initiating rollback on " -                       "followers and the leader " -                       "respectively."); - -                /* TODO: PERFORM ROLLBACK OF LOCKING ON -                 * FOLLOWERS, FOLLOWED BY ROLLBACK ON -                 * LEADER. -                 */ - -                STACK_UNWIND_STRICT(lk, frame, -1, EROFS, flock, xdata); -            } else { -                STACK_UNWIND_STRICT(lk, frame, 0, 0, flock, xdata); -            } -        } -    } - -    ret = 0; -out: -    return ret; -} - -/* - * Called from leader for locking fop, being written as a separate - * function so as to support queues. - */ -int32_t -jbr_perform_lk_on_leader(call_frame_t *frame, xlator_t *this, fd_t *fd, -                         int32_t cmd, struct gf_flock *flock, dict_t *xdata) -{ -    int32_t ret = -1; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    GF_VALIDATE_OR_GOTO(this->name, flock, out); -    GF_VALIDATE_OR_GOTO(this->name, fd, out); - -    STACK_WIND(frame, jbr_lk_complete, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lk, fd, cmd, flock, xdata); - -    ret = 0; -out: -    return ret; -} - -int32_t -jbr_lk_perform_local_op(call_frame_t *frame, xlator_t *this, int *op_errno, -                        fd_t *fd, int32_t cmd, struct gf_flock *flock, -                        dict_t *xdata) -{ -    int32_t ret = -1; -    jbr_local_t *local = NULL; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, out); -    GF_VALIDATE_OR_GOTO(this->name, fd, out); -    GF_VALIDATE_OR_GOTO(this->name, op_errno, out); -    GF_VALIDATE_OR_GOTO(this->name, flock, out); - -    /* -     * Check if the fop is a locking fop or unlocking fop, and -     * handle it accordingly. If it is a locking fop, take the -     * lock on leader first, and then send it to the followers. -     * If it is a unlocking fop, unlock the followers first, -     * and then on meeting quorum perform the unlock on the leader. -     */ -    if (flock->l_type == F_UNLCK) { -        ret = jbr_lk_call_dispatch(frame, this, op_errno, fd, cmd, flock, -                                   xdata); -        if (ret) -            goto out; -    } else { -        jbr_inode_ctx_t *ictx = jbr_get_inode_ctx(this, fd->inode); - -        if (!ictx) { -            *op_errno = EIO; -            goto out; -        } - -        LOCK(&ictx->lock); -        if (ictx->active) { -            gf_msg_debug(this->name, 0, "queuing request due to conflict"); - -            local->qstub = fop_lk_stub(frame, jbr_perform_lk_on_leader, fd, cmd, -                                       flock, xdata); -            if (!local->qstub) { -                UNLOCK(&ictx->lock); -                goto out; -            } -            list_add_tail(&local->qlinks, &ictx->pqueue); -            ++(ictx->pending); -            UNLOCK(&ictx->lock); -            ret = 0; -            goto out; -        } else { -            list_add_tail(&local->qlinks, &ictx->aqueue); -            ++(ictx->active); -        } -        UNLOCK(&ictx->lock); -        ret = jbr_perform_lk_on_leader(frame, this, fd, cmd, flock, xdata); -        if (ret == -1) -            goto out; -    } - -    ret = 0; -out: -    return ret; -} - -int32_t -jbr_lk_continue(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, -                struct gf_flock *flock, dict_t *xdata) -{ -    int32_t ret = -1; -    jbr_local_t *local = NULL; -    jbr_private_t *priv = NULL; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    priv = this->private; -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, priv, out); -    GF_VALIDATE_OR_GOTO(this->name, local, out); -    GF_VALIDATE_OR_GOTO(this->name, flock, out); -    GF_VALIDATE_OR_GOTO(this->name, fd, out); -    GF_VALIDATE_OR_GOTO(this->name, xdata, out); - -    /* -     * If it's a locking fop, then call dispatch to followers  * -     * If it's a unlock fop, then perform the unlock operation * -     */ -    if (flock->l_type == F_UNLCK) { -        STACK_WIND(frame, jbr_lk_complete, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->lk, fd, cmd, flock, xdata); -    } else { -        /* -         * Directly call jbr_lk_dispatch instead of appending * -         * in queue, which is done at jbr_lk_perform_local_op * -         * for locking fops                                   * -         */ -        ret = jbr_lk_dispatch(frame, this, fd, cmd, flock, xdata); -        if (ret) { -            STACK_UNWIND_STRICT(lk, frame, -1, 0, flock, xdata); -            goto out; -        } -    } - -    ret = 0; -out: -    return ret; -} - -uint8_t -jbr_count_up_kids(jbr_private_t *priv) -{ -    uint8_t retval = 0; -    uint8_t i; - -    for (i = 0; i < priv->n_children; ++i) { -        if (priv->kid_state & (1 << i)) { -            ++retval; -        } -    } - -    return retval; -} - -/* - * The fsync machinery looks a lot like that for any write call, but there are - * some important differences that are easy to miss.  First, we don't care - * about the xdata that shows whether the call came from a leader or - * reconciliation process.  If we're the leader we fan out; if we're not we - * don't.  Second, we don't wait for followers before we issue the local call. - * The code generation system could be updated to handle this, and still might - * if we need to implement other "almost identical" paths (e.g. for open), but - * a copy is more readable as long as it's just one. - */ - -int32_t -jbr_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, -              dict_t *xdata) -{ -    jbr_local_t *local = frame->local; -    gf_boolean_t unwind; - -    LOCK(&frame->lock); -    unwind = !--(local->call_count); -    UNLOCK(&frame->lock); - -    if (unwind) { -        STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, -                            xdata); -    } -    return 0; -} - -int32_t -jbr_fsync_local_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                    struct iatt *postbuf, dict_t *xdata) -{ -    jbr_dirty_list_t *dirty; -    jbr_dirty_list_t *dtmp; -    jbr_local_t *local = frame->local; - -    list_for_each_entry_safe(dirty, dtmp, &local->qlinks, links) -    { -        gf_msg_trace(this->name, 0, "sending post-op on %p (%p)", local->fd, -                     dirty); -        GF_FREE(dirty); -    } - -    return jbr_fsync_cbk(frame, cookie, this, op_ret, op_errno, prebuf, postbuf, -                         xdata); -} - -int32_t -jbr_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, -          dict_t *xdata) -{ -    jbr_private_t *priv = this->private; -    jbr_local_t *local; -    uint64_t ctx_int = 0LL; -    jbr_fd_ctx_t *ctx_ptr; -    xlator_list_t *trav; - -    local = mem_get0(this->local_pool); -    if (!local) { -        STACK_UNWIND_STRICT(fsync, frame, -1, ENOMEM, NULL, NULL, xdata); -        return 0; -    } -    INIT_LIST_HEAD(&local->qlinks); -    frame->local = local; - -    /* Move the dirty list from the fd to the fsync request. */ -    LOCK(&fd->lock); -    if (__fd_ctx_get(fd, this, &ctx_int) == 0) { -        ctx_ptr = (jbr_fd_ctx_t *)(long)ctx_int; -        list_splice_init(&ctx_ptr->dirty_list, &local->qlinks); -    } -    UNLOCK(&fd->lock); - -    /* Issue the local call. */ -    local->call_count = priv->leader ? priv->n_children : 1; -    STACK_WIND(frame, jbr_fsync_local_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); - -    /* Issue remote calls if we're the leader. */ -    if (priv->leader) { -        for (trav = this->children->next; trav; trav = trav->next) { -            STACK_WIND(frame, jbr_fsync_cbk, FIRST_CHILD(this), -                       FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); -        } -    } - -    return 0; -} - -int32_t -jbr_getxattr_special(call_frame_t *frame, xlator_t *this, loc_t *loc, -                     const char *name, dict_t *xdata) -{ -    dict_t *result; -    jbr_private_t *priv = this->private; - -    if (!priv->leader) { -        STACK_UNWIND_STRICT(getxattr, frame, -1, EREMOTE, NULL, NULL); -        return 0; -    } - -    if (!name || (strcmp(name, JBR_REP_COUNT_XATTR) != 0)) { -        STACK_WIND_TAIL(frame, FIRST_CHILD(this), -                        FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); -        return 0; -    } - -    result = dict_new(); -    if (!result) { -        goto dn_failed; -    } - -    priv->up_children = jbr_count_up_kids(this->private); -    if (dict_set_uint32(result, JBR_REP_COUNT_XATTR, priv->up_children) != 0) { -        goto dsu_failed; -    } - -    STACK_UNWIND_STRICT(getxattr, frame, 0, 0, result, NULL); -    dict_unref(result); -    return 0; - -dsu_failed: -    dict_unref(result); -dn_failed: -    STACK_UNWIND_STRICT(getxattr, frame, -1, ENOMEM, NULL, NULL); -    return 0; -} - -void -jbr_flush_fd(xlator_t *this, jbr_fd_ctx_t *fd_ctx) -{ -    jbr_dirty_list_t *dirty; -    jbr_dirty_list_t *dtmp; - -    list_for_each_entry_safe(dirty, dtmp, &fd_ctx->dirty_list, links) -    { -        gf_msg_trace(this->name, 0, "sending post-op on %p (%p)", fd_ctx->fd, -                     dirty); -        GF_FREE(dirty); -    } - -    INIT_LIST_HEAD(&fd_ctx->dirty_list); -} - -void * -jbr_flush_thread(void *ctx) -{ -    xlator_t *this = ctx; -    jbr_private_t *priv = this->private; -    struct list_head dirty_fds; -    jbr_fd_ctx_t *fd_ctx; -    jbr_fd_ctx_t *fd_tmp; -    int ret; - -    for (;;) { -        /* -         * We have to be very careful to avoid lock inversions here, so -         * we can't just hold priv->dirty_lock while we take and -         * release locks for each fd.  Instead, we only hold dirty_lock -         * at the beginning of each iteration, as we (effectively) make -         * a copy of the current list head and then clear the original. -         * This leads to four scenarios for adding the first entry to -         * an fd and potentially putting it on the global list. -         * -         * (1) While we're asleep.  No lock contention, it just gets -         *     added and will be processed on the next iteration. -         * -         * (2) After we've made a local copy, but before we've started -         *     processing that fd.  The new entry will be added to the -         *     fd (under its lock), and we'll process it on the current -         *     iteration. -         * -         * (3) While we're processing the fd.  They'll block on the fd -         *     lock, then see that the list is empty and put it on the -         *     global list.  We'll process it here on the next -         *     iteration. -         * -         * (4) While we're working, but after we've processed that fd. -         *     Same as (1) as far as that fd is concerned. -         */ -        INIT_LIST_HEAD(&dirty_fds); -        LOCK(&priv->dirty_lock); -        list_splice_init(&priv->dirty_fds, &dirty_fds); -        UNLOCK(&priv->dirty_lock); - -        list_for_each_entry_safe(fd_ctx, fd_tmp, &dirty_fds, fd_list) -        { -            ret = syncop_fsync(FIRST_CHILD(this), fd_ctx->fd, 0, NULL, NULL, -                               NULL, NULL); -            if (ret) { -                gf_msg(this->name, GF_LOG_WARNING, 0, J_MSG_SYS_CALL_FAILURE, -                       "failed to fsync %p (%d)", fd_ctx->fd, -ret); -            } - -            LOCK(&fd_ctx->fd->lock); -            jbr_flush_fd(this, fd_ctx); -            list_del_init(&fd_ctx->fd_list); -            UNLOCK(&fd_ctx->fd->lock); -            fd_unref(fd_ctx->fd); -        } - -        sleep(JBR_FLUSH_INTERVAL); -    } - -    return NULL; -} - -int32_t -jbr_get_changelog_dir(xlator_t *this, char **cl_dir_p) -{ -    xlator_t *cl_xl; - -    /* Find our changelog translator. */ -    cl_xl = this; -    while (cl_xl) { -        if (strcmp(cl_xl->type, "features/changelog") == 0) { -            break; -        } -        cl_xl = cl_xl->children->xlator; -    } -    if (!cl_xl) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_INIT_FAIL, -               "failed to find changelog translator"); -        return ENOENT; -    } - -    /* Find the actual changelog directory. */ -    if (dict_get_str(cl_xl->options, "changelog-dir", cl_dir_p) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_INIT_FAIL, -               "failed to find changelog-dir for %s", cl_xl->name); -        return ENODATA; -    } - -    return 0; -} - -void -jbr_get_terms(call_frame_t *frame, xlator_t *this) -{ -    int32_t op_errno = 0; -    char *cl_dir = NULL; -    int32_t term_first = -1; -    int32_t term_contig = -1; -    int32_t term_last = -1; -    int term_num = 0; -    char *probe_str = NULL; -    dict_t *my_xdata = NULL; -    DIR *fp = NULL; -    struct dirent *entry = NULL; -    struct dirent scratch[2] = { -        { -            0, -        }, -    }; - -    op_errno = jbr_get_changelog_dir(this, &cl_dir); -    if (op_errno) { -        goto err; /* Error was already logged. */ -    } -    op_errno = ENODATA; /* Most common error after this. */ - -    fp = sys_opendir(cl_dir); -    if (!fp) { -        op_errno = errno; -        goto err; -    } - -    /* Find first and last terms. */ -    for (;;) { -        errno = 0; -        entry = sys_readdir(fp, scratch); -        if (!entry || errno != 0) { -            if (errno != 0) { -                op_errno = errno; -                goto err; -            } -            break; -        } - -        if (fnmatch("TERM.*", entry->d_name, FNM_PATHNAME) != 0) { -            continue; -        } -        /* +5 points to the character after the period */ -        term_num = atoi(entry->d_name + 5); -        gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, "%s => %d", -               entry->d_name, term_num); -        if (term_num < 0) { -            gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_INVALID, -                   "invalid term file name %s", entry->d_name); -            op_errno = EINVAL; -            goto err; -        } -        if ((term_first < 0) || (term_first > term_num)) { -            term_first = term_num; -        } -        if ((term_last < 0) || (term_last < term_num)) { -            term_last = term_num; -        } -    } -    if ((term_first < 0) || (term_last < 0)) { -        /* TBD: are we *sure* there should always be at least one? */ -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_NO_DATA, "no terms found"); -        op_errno = EINVAL; -        goto err; -    } - -    (void)sys_closedir(fp); -    fp = NULL; - -    /* -     * Find term_contig, which is the earliest term for which there are -     * no gaps between it and term_last. -     */ -    for (term_contig = term_last; term_contig > 0; --term_contig) { -        if (gf_asprintf(&probe_str, "%s/TERM.%d", cl_dir, term_contig - 1) <= -            0) { -            gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_MEM_ERR, -                   "failed to format term %d", term_contig - 1); -            goto err; -        } -        if (sys_access(probe_str, F_OK) != 0) { -            GF_FREE(probe_str); -            probe_str = NULL; -            break; -        } -        GF_FREE(probe_str); -        probe_str = NULL; -    } - -    gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, "found terms %d-%d (%d)", -           term_first, term_last, term_contig); - -    /* Return what we've found */ -    my_xdata = dict_new(); -    if (!my_xdata) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_MEM_ERR, -               "failed to allocate reply dictionary"); -        goto err; -    } -    if (dict_set_int32(my_xdata, "term-first", term_first) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -               "failed to set term-first"); -        goto err; -    } -    if (dict_set_int32(my_xdata, "term-contig", term_contig) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -               "failed to set term-contig"); -        goto err; -    } -    if (dict_set_int32(my_xdata, "term-last", term_last) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -               "failed to set term-last"); -        goto err; -    } - -    /* Finally! */ -    STACK_UNWIND_STRICT(ipc, frame, 0, 0, my_xdata); -    dict_unref(my_xdata); -    return; - -err: -    if (fp) { -        (void)sys_closedir(fp); -    } -    if (my_xdata) { -        dict_unref(my_xdata); -    } - -    if (probe_str) -        GF_FREE(probe_str); - -    STACK_UNWIND_STRICT(ipc, frame, -1, op_errno, NULL); -} - -long -get_entry_count(xlator_t *this, int fd) -{ -    struct stat buf; -    long min; /* last entry not known to be empty */ -    long max; /* first entry known to be empty */ -    long curr; -    char entry[CHANGELOG_ENTRY_SIZE]; - -    if (sys_fstat(fd, &buf) < 0) { -        return -1; -    } - -    min = 0; -    max = buf.st_size / CHANGELOG_ENTRY_SIZE; - -    while ((min + 1) < max) { -        curr = (min + max) / 2; -        if (sys_lseek(fd, curr * CHANGELOG_ENTRY_SIZE, SEEK_SET) < 0) { -            return -1; -        } -        if (sys_read(fd, entry, sizeof(entry)) != sizeof(entry)) { -            return -1; -        } -        if ((entry[0] == '_') && (entry[1] == 'P')) { -            min = curr; -        } else { -            max = curr; -        } -    } - -    if (sys_lseek(fd, 0, SEEK_SET) < 0) { -        gf_msg(this->name, GF_LOG_WARNING, 0, J_MSG_SYS_CALL_FAILURE, -               "failed to reset offset"); -    } -    return max; -} - -void -jbr_open_term(call_frame_t *frame, xlator_t *this, dict_t *xdata) -{ -    int32_t op_errno; -    char *cl_dir; -    char *term; -    char *path = NULL; -    jbr_private_t *priv = this->private; - -    op_errno = jbr_get_changelog_dir(this, &cl_dir); -    if (op_errno) { -        goto err; -    } - -    if (dict_get_str(xdata, "term", &term) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_NO_DATA, "missing term"); -        op_errno = ENODATA; -        goto err; -    } - -    if (gf_asprintf(&path, "%s/TERM.%s", cl_dir, term) < 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_MEM_ERR, -               "failed to construct path"); -        op_errno = ENOMEM; -        goto err; -    } - -    if (priv->term_fd >= 0) { -        sys_close(priv->term_fd); -    } -    priv->term_fd = open(path, O_RDONLY); -    if (priv->term_fd < 0) { -        op_errno = errno; -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_SYS_CALL_FAILURE, -               "failed to open term file"); -        goto err; -    } - -    priv->term_total = get_entry_count(this, priv->term_fd); -    if (priv->term_total < 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_NO_DATA, -               "failed to get entry count"); -        sys_close(priv->term_fd); -        priv->term_fd = -1; -        op_errno = EIO; -        goto err; -    } -    priv->term_read = 0; - -    /* Success! */ -    STACK_UNWIND_STRICT(ipc, frame, 0, 0, NULL); -    GF_FREE(path); -    return; - -err: -    STACK_UNWIND_STRICT(ipc, frame, -1, op_errno, NULL); -    GF_FREE(path); -} - -void -jbr_next_entry(call_frame_t *frame, xlator_t *this) -{ -    int32_t op_errno = ENOMEM; -    jbr_private_t *priv = this->private; -    ssize_t nbytes; -    dict_t *my_xdata; - -    if (priv->term_fd < 0) { -        op_errno = EBADFD; -        goto err; -    } - -    if (priv->term_read >= priv->term_total) { -        op_errno = ENODATA; -        goto err; -    } - -    nbytes = sys_read(priv->term_fd, priv->term_buf, CHANGELOG_ENTRY_SIZE); -    if (nbytes < CHANGELOG_ENTRY_SIZE) { -        if (nbytes < 0) { -            op_errno = errno; -            gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_SYS_CALL_FAILURE, -                   "error reading next entry: %s", strerror(errno)); -        } else { -            op_errno = EIO; -            gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_SYS_CALL_FAILURE, -                   "got %zd/%d bytes for next entry", nbytes, -                   CHANGELOG_ENTRY_SIZE); -        } -        goto err; -    } -    ++(priv->term_read); - -    my_xdata = dict_new(); -    if (!my_xdata) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_MEM_ERR, -               "failed to allocate reply xdata"); -        goto err; -    } - -    if (dict_set_static_bin(my_xdata, "data", priv->term_buf, -                            CHANGELOG_ENTRY_SIZE) != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_DICT_FLR, -               "failed to assign reply xdata"); -        goto err; -    } - -    STACK_UNWIND_STRICT(ipc, frame, 0, 0, my_xdata); -    dict_unref(my_xdata); -    return; - -err: -    STACK_UNWIND_STRICT(ipc, frame, -1, op_errno, NULL); -} - -int32_t -jbr_ipc_fan_in(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    jbr_local_t *local = NULL; -    int32_t ret = -1; -    uint8_t call_count; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, out); - -    gf_msg_trace(this->name, 0, "op_ret = %d, op_errno = %d\n", op_ret, -                 op_errno); - -    LOCK(&frame->lock); -    call_count = --(local->call_count); -    UNLOCK(&frame->lock); - -    if (call_count == 0) { -#if defined(JBR_CG_QUEUE) -        ret = jbr_remove_from_queue(frame, this); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_GENERIC, -                   "Failed to remove from queue."); -        } -#endif -        /* -         * Unrefing the reference taken in continue() or complete() * -         */ -        dict_unref(local->xdata); -        STACK_DESTROY(frame->root); -    } - -    ret = 0; -out: -    return ret; -} - -int32_t -jbr_ipc_complete(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    jbr_local_t *local = NULL; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, frame, out); -    local = frame->local; -    GF_VALIDATE_OR_GOTO(this->name, local, out); - -    jbr_ipc_call_dispatch(frame, this, &op_errno, FDL_IPC_JBR_SERVER_ROLLBACK, -                          local->xdata); -out: -    return 0; -} - -int32_t -jbr_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) -{ -    switch (op) { -        case JBR_SERVER_TERM_RANGE: -            jbr_get_terms(frame, this); -            break; -        case JBR_SERVER_OPEN_TERM: -            jbr_open_term(frame, this, xdata); -            break; -        case JBR_SERVER_NEXT_ENTRY: -            jbr_next_entry(frame, this); -            break; -        case FDL_IPC_JBR_SERVER_ROLLBACK: -            /* -             * Just send the fop down to fdl. Need not * -             * dispatch it to other bricks in the sub- * -             * volume, as it will be done where the op * -             * has failed.                             * -             */ -        default: -            STACK_WIND_TAIL(frame, FIRST_CHILD(this), -                            FIRST_CHILD(this)->fops->ipc, op, xdata); -    } - -    return 0; -} - -#pragma generate - -int32_t -jbr_forget(xlator_t *this, inode_t *inode) -{ -    uint64_t ctx = 0LL; - -    if ((inode_ctx_del(inode, this, &ctx) == 0) && ctx) { -        GF_FREE((void *)(long)ctx); -    } - -    return 0; -} - -int32_t -jbr_release(xlator_t *this, fd_t *fd) -{ -    uint64_t ctx = 0LL; - -    if ((fd_ctx_del(fd, this, &ctx) == 0) && ctx) { -        GF_FREE((void *)(long)ctx); -    } - -    return 0; -} - -struct xlator_cbks cbks = { -    .forget = jbr_forget, -    .release = jbr_release, -}; - -int -jbr_reconfigure(xlator_t *this, dict_t *options) -{ -    jbr_private_t *priv = this->private; - -    GF_OPTION_RECONF("leader", priv->config_leader, options, bool, err); -    GF_OPTION_RECONF("quorum-percent", priv->quorum_pct, options, percent, err); -    gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -           "reconfigure called, config_leader = %d, quorum_pct = %.1f\n", -           priv->leader, priv->quorum_pct); - -    priv->leader = priv->config_leader; - -    return 0; - -err: -    return -1; -} - -int -jbr_get_child_index(xlator_t *this, xlator_t *kid) -{ -    xlator_list_t *trav; -    int retval = -1; - -    for (trav = this->children; trav; trav = trav->next) { -        ++retval; -        if (trav->xlator == kid) { -            return retval; -        } -    } - -    return -1; -} - -/* - * Child notify handling is unreasonably FUBAR.  Sometimes we'll get a - * CHILD_DOWN for a protocol/client child before we ever got a CHILD_UP for it. - * Other times we won't.  Because it's effectively random (probably racy), we - * can't just maintain a count.  We actually have to keep track of the state - * for each child separately, to filter out the bogus CHILD_DOWN events, and - * then generate counts on demand. - */ -int -jbr_notify(xlator_t *this, int event, void *data, ...) -{ -    jbr_private_t *priv = this->private; -    int index = -1; -    int ret = -1; -    gf_boolean_t result = _gf_false; -    gf_boolean_t relevant = _gf_false; - -    switch (event) { -        case GF_EVENT_CHILD_UP: -            index = jbr_get_child_index(this, data); -            if (index >= 0) { -                /* Check if the child was previously down -                 * and it's not a false CHILD_UP -                 */ -                if (!(priv->kid_state & (1 << index))) { -                    relevant = _gf_true; -                } - -                priv->kid_state |= (1 << index); -                priv->up_children = jbr_count_up_kids(priv); -                gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                       "got CHILD_UP for %s, now %u kids", -                       ((xlator_t *)data)->name, priv->up_children); -                if (!priv->config_leader && (priv->up_children > 1)) { -                    priv->leader = _gf_false; -                } - -                /* If it's not relevant, or we have already * -                 * sent CHILD_UP just break */ -                if (!relevant || priv->child_up) -                    break; - -                /* If it's not a leader, just send the notify up */ -                if (!priv->leader) { -                    ret = default_notify(this, event, data); -                    if (!ret) -                        priv->child_up = _gf_true; -                    break; -                } - -                result = fop_quorum_check(this, (double)(priv->n_children - 1), -                                          (double)(priv->up_children - 1)); -                if (result == _gf_false) { -                    gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                           "Not enough children " -                           "are up to meet quorum. Waiting to " -                           "send CHILD_UP from leader"); -                } else { -                    gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                           "Enough children are up " -                           "to meet quorum. Sending CHILD_UP " -                           "from leader"); -                    ret = default_notify(this, event, data); -                    if (!ret) -                        priv->child_up = _gf_true; -                } -            } -            break; -        case GF_EVENT_CHILD_DOWN: -            index = jbr_get_child_index(this, data); -            if (index >= 0) { -                /* Check if the child was previously up -                 * and it's not a false CHILD_DOWN -                 */ -                if (priv->kid_state & (1 << index)) { -                    relevant = _gf_true; -                } -                priv->kid_state &= ~(1 << index); -                priv->up_children = jbr_count_up_kids(priv); -                gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                       "got CHILD_DOWN for %s, now %u kids", -                       ((xlator_t *)data)->name, priv->up_children); -                if (!priv->config_leader && (priv->up_children < 2) && -                    relevant) { -                    priv->leader = _gf_true; -                } - -                /* If it's not relevant, or we have already * -                 * sent CHILD_DOWN just break */ -                if (!relevant || !priv->child_up) -                    break; - -                /* If it's not a leader, just break coz we shouldn't  * -                 * propagate the failure from the failure till it     * -                 * itself goes down                                   * -                 */ -                if (!priv->leader) { -                    break; -                } - -                result = fop_quorum_check(this, (double)(priv->n_children - 1), -                                          (double)(priv->up_children - 1)); -                if (result == _gf_false) { -                    gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                           "Enough children are " -                           "to down to fail quorum. " -                           "Sending CHILD_DOWN from leader"); -                    ret = default_notify(this, event, data); -                    if (!ret) -                        priv->child_up = _gf_false; -                } else { -                    gf_msg(this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, -                           "Not enough children " -                           "are down to fail quorum. Waiting to " -                           "send CHILD_DOWN from leader"); -                } -            } -            break; -        default: -            ret = default_notify(this, event, data); -    } - -    return ret; -} - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    GF_VALIDATE_OR_GOTO("jbr", this, out); - -    ret = xlator_mem_acct_init(this, gf_mt_jbr_end + 1); - -    if (ret != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_MEM_ERR, -               "Memory accounting init" -               "failed"); -        return ret; -    } -out: -    return ret; -} - -void -jbr_deallocate_priv(jbr_private_t *priv) -{ -    if (!priv) { -        return; -    } - -    GF_FREE(priv); -} - -int32_t -jbr_init(xlator_t *this) -{ -    xlator_list_t *remote; -    xlator_list_t *local; -    jbr_private_t *priv = NULL; -    xlator_list_t *trav; -    pthread_t kid; -    extern xlator_t global_xlator; -    glusterfs_ctx_t *oldctx = global_xlator.ctx; - -    /* -     * Any fop that gets special treatment has to be patched in here, -     * because the compiled-in table is produced by the code generator and -     * only contains generated functions.  Note that we have to go through -     * this->fops because of some dynamic-linking strangeness; modifying -     * the static table doesn't work. -     */ -    this->fops->getxattr = jbr_getxattr_special; -    this->fops->fsync = jbr_fsync; - -    local = this->children; -    if (!local) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_NO_DATA, -               "no local subvolume"); -        goto err; -    } - -    remote = local->next; -    if (!remote) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_NO_DATA, -               "no remote subvolumes"); -        goto err; -    } - -    this->local_pool = mem_pool_new(jbr_local_t, 128); -    if (!this->local_pool) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_MEM_ERR, -               "failed to create jbr_local_t pool"); -        goto err; -    } - -    priv = GF_CALLOC(1, sizeof(*priv), gf_mt_jbr_private_t); -    if (!priv) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_MEM_ERR, -               "could not allocate priv"); -        goto err; -    } - -    for (trav = this->children; trav; trav = trav->next) { -        ++(priv->n_children); -    } - -    LOCK_INIT(&priv->dirty_lock); -    LOCK_INIT(&priv->index_lock); -    INIT_LIST_HEAD(&priv->dirty_fds); -    priv->term_fd = -1; - -    this->private = priv; - -    GF_OPTION_INIT("leader", priv->config_leader, bool, err); -    GF_OPTION_INIT("quorum-percent", priv->quorum_pct, percent, err); - -    priv->leader = priv->config_leader; -    priv->child_up = _gf_false; - -    if (gf_thread_create(&kid, NULL, jbr_flush_thread, this, "jbrflush") != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, J_MSG_SYS_CALL_FAILURE, -               "could not start flush thread"); -        /* TBD: treat this as a fatal error? */ -    } - -    /* -     * Calling glfs_new changes old->ctx, even if THIS still points -     * to global_xlator.  That causes problems later in the main -     * thread, when gf_log_dump_graph tries to use the FILE after -     * we've mucked with it and gets a segfault in __fprintf_chk. -     * We can avoid all that by undoing the damage before we -     * continue. -     */ -    global_xlator.ctx = oldctx; - -    return 0; - -err: -    jbr_deallocate_priv(priv); -    return -1; -} - -void -jbr_fini(xlator_t *this) -{ -    jbr_deallocate_priv(this->private); -} - -class_methods_t class_methods = { -    .init = jbr_init, -    .fini = jbr_fini, -    .reconfigure = jbr_reconfigure, -    .notify = jbr_notify, -}; - -struct volume_options options[] = { -    {.key = {"leader"}, -     .type = GF_OPTION_TYPE_BOOL, -     .default_value = "false", -     .description = "Start in the leader role.  This is only for " -                    "bootstrapping the code, and should go away when we " -                    "have real leader election."}, -    {.key = {"vol-name"}, -     .type = GF_OPTION_TYPE_STR, -     .description = "volume name"}, -    {.key = {"my-name"}, -     .type = GF_OPTION_TYPE_STR, -     .description = "brick name in form of host:/path"}, -    {.key = {"etcd-servers"}, -     .type = GF_OPTION_TYPE_STR, -     .description = "list of comma separated etc servers"}, -    {.key = {"subvol-uuid"}, -     .type = GF_OPTION_TYPE_STR, -     .description = "UUID for this JBR (sub)volume"}, -    {.key = {"quorum-percent"}, -     .type = GF_OPTION_TYPE_PERCENT, -     .default_value = "50.0", -     .description = "percentage of rep_count-1 that must be up"}, -    {.key = {NULL}}, -}; diff --git a/xlators/experimental/posix2/Makefile.am b/xlators/experimental/posix2/Makefile.am deleted file mode 100644 index 74e5ab0f5bc..00000000000 --- a/xlators/experimental/posix2/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = common mds ds - -CLEANFILES = diff --git a/xlators/experimental/posix2/README.md b/xlators/experimental/posix2/README.md deleted file mode 100644 index 955a98d061e..00000000000 --- a/xlators/experimental/posix2/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# POSIX2 Experimental README - -POSIX2 is an implementation of modified storage translator to cater to DHT2 -on disk needs. - -For further understanding, refer to xlators/experimental/dht2/README.md for -details regarding POSIX2 diff --git a/xlators/experimental/posix2/TODO.md b/xlators/experimental/posix2/TODO.md deleted file mode 100644 index 20cd1e89c1d..00000000000 --- a/xlators/experimental/posix2/TODO.md +++ /dev/null @@ -1,3 +0,0 @@ -# POSIX2 TODO List - -<Items will be added as code is pulled into the repository>
\ No newline at end of file diff --git a/xlators/experimental/posix2/common/Makefile.am b/xlators/experimental/posix2/common/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/posix2/common/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/posix2/common/src/Makefile.am b/xlators/experimental/posix2/common/src/Makefile.am deleted file mode 100644 index 07533d2bf37..00000000000 --- a/xlators/experimental/posix2/common/src/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -lib_LTLIBRARIES = libposix2common.la - -posix2_common_sources = posix2-common.c - -libposix2common_la_SOURCES = $(posix2_common_sources) -libposix2common_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -libposix2common_la_CFLAGS = -Wall $(GF_CFLAGS) - -libposix2common_la_CPPFLAGS = $(GF_CPPFLAGS) -libposix2common_la_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src -libposix2common_la_CPPFLAGS += -I$(top_srcdir)/rpc/xdr/src -libposix2common_la_CPPFLAGS += -I$(top_builddir)/rpc/xdr/src - - -CLEANFILES = diff --git a/xlators/experimental/posix2/common/src/posix2-common.c b/xlators/experimental/posix2/common/src/posix2-common.c deleted file mode 100644 index 06702528bec..00000000000 --- a/xlators/experimental/posix2/common/src/posix2-common.c +++ /dev/null @@ -1,18 +0,0 @@ -/* -  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -/* File: posix2-common.c - * This file contains common routines across ds and mds posix xlators - * The entire functionality including comments is TODO. - */ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/logging.h> -#include <glusterfs/statedump.h> diff --git a/xlators/experimental/posix2/ds/Makefile.am b/xlators/experimental/posix2/ds/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/posix2/ds/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/posix2/ds/src/Makefile.am b/xlators/experimental/posix2/ds/src/Makefile.am deleted file mode 100644 index 7a792a8d07b..00000000000 --- a/xlators/experimental/posix2/ds/src/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -if WITH_SERVER -xlator_LTLIBRARIES = posix2-ds.la -endif -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental - -posix2_ds_sources = posix2-ds-main.c - -posix2_ds_la_SOURCES = $(posix2_ds_sources) -posix2_ds_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -posix2_ds_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -posix2_ds_la_LIBADD += $(top_builddir)/xlators/experimental/posix2/common/src/libposix2common.la - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -AM_CPPFLAGS = $(GF_CPPFLAGS) -AM_CPPFLAGS += -I$(top_srcdir)/xlators/storage/posix2/common/src -AM_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src -AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src -AM_CPPFLAGS += -I$(top_srcdir)/rpc/xdr/src -AM_CPPFLAGS += -I$(top_builddir)/rpc/xdr/src - -CLEANFILES = diff --git a/xlators/experimental/posix2/ds/src/posix2-ds-main.c b/xlators/experimental/posix2/ds/src/posix2-ds-main.c deleted file mode 100644 index 0d3a026611e..00000000000 --- a/xlators/experimental/posix2/ds/src/posix2-ds-main.c +++ /dev/null @@ -1,56 +0,0 @@ -/* -  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -/* File: posix2-ds-main.c - * This file contains the xlator loading functions, FOP entry points - * and options. - * The entire functionality including comments is TODO. - */ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/statedump.h> - -int32_t -posix2_ds_init(xlator_t *this) -{ -    if (this->children) { -        gf_log(this->name, GF_LOG_ERROR, -               "This (%s) is a leaf xlator, but found children", this->name); -        return -1; -    } - -    return 0; -} - -void -posix2_ds_fini(xlator_t *this) -{ -    return; -} - -class_methods_t class_methods = { -    .init = posix2_ds_init, -    .fini = posix2_ds_fini, -}; - -struct xlator_fops fops = {}; - -struct xlator_cbks cbks = {}; - -/* -struct xlator_dumpops dumpops = { -}; -*/ - -struct volume_options options[] = { -    {.key = {NULL}}, -}; diff --git a/xlators/experimental/posix2/mds/Makefile.am b/xlators/experimental/posix2/mds/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/experimental/posix2/mds/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/experimental/posix2/mds/src/Makefile.am b/xlators/experimental/posix2/mds/src/Makefile.am deleted file mode 100644 index 0681cb73c45..00000000000 --- a/xlators/experimental/posix2/mds/src/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -if WITH_SERVER -xlator_LTLIBRARIES = posix2-mds.la -endif -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental - -posix2_mds_sources = posix2-mds-main.c - -posix2_mds_la_SOURCES = $(posix2_mds_sources) -posix2_mds_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -posix2_mds_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -posix2_mds_la_LIBADD += $(top_builddir)/xlators/experimental/posix2/common/src/libposix2common.la - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -AM_CPPFLAGS = $(GF_CPPFLAGS) -AM_CPPFLAGS += -I$(top_srcdir)/xlators/storage/posix2/common/src -AM_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src -AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src -AM_CPPFLAGS += -I$(top_srcdir)/rpc/xdr/src -AM_CPPFLAGS += -I$(top_builddir)/rpc/xdr/src - -CLEANFILES = diff --git a/xlators/experimental/posix2/mds/src/posix2-mds-main.c b/xlators/experimental/posix2/mds/src/posix2-mds-main.c deleted file mode 100644 index f2ec570917d..00000000000 --- a/xlators/experimental/posix2/mds/src/posix2-mds-main.c +++ /dev/null @@ -1,56 +0,0 @@ -/* -  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -/* File: posix2-mds-main.c - * This file contains the xlator loading functions, FOP entry points - * and options. - * The entire functionality including comments is TODO. - */ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/statedump.h> - -int32_t -posix2_mds_init(xlator_t *this) -{ -    if (this->children) { -        gf_log(this->name, GF_LOG_ERROR, -               "This (%s) is a leaf xlator, but found children", this->name); -        return -1; -    } - -    return 0; -} - -void -posix2_mds_fini(xlator_t *this) -{ -    return; -} - -class_methods_t class_methods = { -    .init = posix2_mds_init, -    .fini = posix2_mds_fini, -}; - -struct xlator_fops fops = {}; - -struct xlator_cbks cbks = {}; - -/* -struct xlator_dumpops dumpops = { -}; -*/ - -struct volume_options options[] = { -    {.key = {NULL}}, -}; diff --git a/xlators/features/changetimerecorder/Makefile.am b/xlators/features/changetimerecorder/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/features/changetimerecorder/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/features/changetimerecorder/src/Makefile.am b/xlators/features/changetimerecorder/src/Makefile.am deleted file mode 100644 index 620017e3309..00000000000 --- a/xlators/features/changetimerecorder/src/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features - -# changetimerecorder can only get build when libgfdb is enabled -if BUILD_GFDB -   xlator_LTLIBRARIES = changetimerecorder.la -endif - -changetimerecorder_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) - -changetimerecorder_la_SOURCES = changetimerecorder.c \ -	ctr-helper.c ctr-xlator-ctx.c - -changetimerecorder_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la\ -	$(top_builddir)/libglusterfs/src/gfdb/libgfdb.la - -noinst_HEADERS = ctr-messages.h changetimerecorder.h ctr_mem_types.h \ -		ctr-helper.h ctr-xlator-ctx.h - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/libglusterfs/src/gfdb \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -	-DDATADIR=\"$(localstatedir)\" - -AM_CFLAGS = -Wall $(GF_CFLAGS) $(SQLITE_CFLAGS) - -CLEANFILES = diff --git a/xlators/features/changetimerecorder/src/changetimerecorder.c b/xlators/features/changetimerecorder/src/changetimerecorder.c deleted file mode 100644 index 1d8068c4f4e..00000000000 --- a/xlators/features/changetimerecorder/src/changetimerecorder.c +++ /dev/null @@ -1,2357 +0,0 @@ -/* -   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ -#include <ctype.h> -#include <sys/uio.h> - -#include "gfdb_sqlite3.h" -#include "ctr-helper.h" -#include "ctr-messages.h" -#include <glusterfs/syscall.h> - -#include "changetimerecorder.h" -#include "tier-ctr-interface.h" - -/*******************************inode forget***********************************/ -int -ctr_forget(xlator_t *this, inode_t *inode) -{ -    fini_ctr_xlator_ctx(this, inode); -    return 0; -} - -/************************** Look up heal **************************************/ -/* -Problem: The CTR xlator records file meta (heat/hardlinks) -into the data. This works fine for files which are created -after ctr xlator is switched ON. But for files which were -created before CTR xlator is ON, CTR xlator is not able to -record either of the meta i.e heat or hardlinks. Thus making -those files immune to promotions/demotions. - -Solution: The solution that is implemented in this patch is -do ctr-db heal of all those pre-existent files, using named lookup. -For this purpose we use the inode-xlator context variable option -in gluster. -The inode-xlator context variable for ctr xlator will have the -following, -    a. A Lock for the context variable -    b. A hardlink list: This list represents the successful looked -       up hardlinks. -These are the scenarios when the hardlink list is updated: -1) Named-Lookup: Whenever a named lookup happens on a file, in the -   wind path we copy all required hardlink and inode information to -   ctr_db_record structure, which resides in the frame->local variable. -   We don't update the database in wind. During the unwind, we read the -   information from the ctr_db_record and , -   Check if the inode context variable is created, if not we create it. -   Check if the hard link is there in the hardlink list. -      If its not there we add it to the list and send a update to the -      database using libgfdb. -      Please note: The database transaction can fail(and we ignore) as there -      already might be a record in the db. This update to the db is to heal -      if its not there. -      If its there in the list we ignore it. -2) Inode Forget: Whenever an inode forget hits we clear the hardlink list in -   the inode context variable and delete the inode context variable. -   Please note: An inode forget may happen for two reason, -   a. when the inode is delete. -   b. the in-memory inode is evicted from the inode table due to cache limits. -3) create: whenever a create happens we create the inode context variable and -   add the hardlink. The database updation is done as usual by ctr. -4) link: whenever a hardlink is created for the inode, we create the inode - context variable, if not present, and add the hardlink to the list. -5) unlink: whenever a unlink happens we delete the hardlink from the list. -6) mknod: same as create. -7) rename: whenever a rename happens we update the hardlink in list. if the -   hardlink was not present for updation, we add the hardlink to the list. - -What is pending: -1) This solution will only work for named lookups. -2) We don't track afr-self-heal/dht-rebalancer traffic for healing. - -*/ - -/* This function does not write anything to the db, - * just created the local variable - * for the frame and sets values for the ctr_db_record */ -static int -ctr_lookup_wind(call_frame_t *frame, xlator_t *this, -                gf_ctr_inode_context_t *ctr_inode_cx) -{ -    int ret = -1; -    gf_ctr_private_t *_priv = NULL; -    gf_ctr_local_t *ctr_local = NULL; - -    GF_ASSERT(frame); -    GF_ASSERT(frame->root); -    GF_ASSERT(this); -    IS_CTR_INODE_CX_SANE(ctr_inode_cx); - -    _priv = this->private; -    GF_ASSERT(_priv); - -    if (_priv->ctr_record_wind && ctr_inode_cx->ia_type != IA_IFDIR) { -        frame->local = init_ctr_local_t(this); -        if (!frame->local) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND, -                   "WIND: Error while creating ctr local"); -            goto out; -        }; -        ctr_local = frame->local; -        /*Definitely no internal fops will reach here*/ -        ctr_local->is_internal_fop = _gf_false; -        /*Don't record counters*/ -        CTR_DB_REC(ctr_local).do_record_counters = _gf_false; -        /*Don't record time at all*/ -        CTR_DB_REC(ctr_local).do_record_times = _gf_false; - -        /* Copy gfid into db record*/ -        gf_uuid_copy(CTR_DB_REC(ctr_local).gfid, *(ctr_inode_cx->gfid)); - -        /* Set fop_path and fop_type, required by libgfdb to make -         * decision while inserting the record */ -        CTR_DB_REC(ctr_local).gfdb_fop_path = ctr_inode_cx->fop_path; -        CTR_DB_REC(ctr_local).gfdb_fop_type = ctr_inode_cx->fop_type; - -        /* Copy hard link info*/ -        gf_uuid_copy(CTR_DB_REC(ctr_local).pargfid, -                     *((NEW_LINK_CX(ctr_inode_cx))->pargfid)); -        if (snprintf(CTR_DB_REC(ctr_local).file_name, -                     sizeof(CTR_DB_REC(ctr_local).file_name), "%s", -                     NEW_LINK_CX(ctr_inode_cx)->basename) >= -            sizeof(CTR_DB_REC(ctr_local).file_name)) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND, -                   "WIND: Error copying filename of ctr local"); -            goto out; -        } -        /* Since we are in lookup we can ignore errors while -         * Inserting in the DB, because there may be many -         * to write to the DB attempts for healing. -         * We don't want to log all failed attempts and -         * bloat the log*/ -        ctr_local->gfdb_db_record.ignore_errors = _gf_true; -    } - -    ret = 0; - -out: - -    if (ret) { -        free_ctr_local(ctr_local); -        frame->local = NULL; -    } - -    return ret; -} - -/* This function inserts the ctr_db_record populated by ctr_lookup_wind - * in to the db. It also destroys the frame->local created by ctr_lookup_wind */ -static int -ctr_lookup_unwind(call_frame_t *frame, xlator_t *this) -{ -    int ret = -1; -    gf_ctr_private_t *_priv = NULL; -    gf_ctr_local_t *ctr_local = NULL; - -    GF_ASSERT(frame); -    GF_ASSERT(this); - -    _priv = this->private; -    GF_ASSERT(_priv); - -    GF_ASSERT(_priv->_db_conn); - -    ctr_local = frame->local; - -    if (ctr_local && (ctr_local->ia_inode_type != IA_IFDIR)) { -        ret = insert_record(_priv->_db_conn, &ctr_local->gfdb_db_record); -        if (ret == -1) { -            gf_msg(this->name, -                   _gfdb_log_level(GF_LOG_ERROR, -                                   ctr_local->gfdb_db_record.ignore_errors), -                   0, CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND, -                   "UNWIND: Error filling ctr local"); -            goto out; -        } -    } -    ret = 0; -out: -    free_ctr_local(ctr_local); -    frame->local = NULL; -    return ret; -} - -/****************************************************************************** - * - *                        FOPS HANDLING BELOW - * - * ***************************************************************************/ - -/****************************LOOKUP********************************************/ - -int32_t -ctr_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, inode_t *inode, -               struct iatt *buf, dict_t *dict, struct iatt *postparent) -{ -    int ret = -1; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; -    gf_ctr_local_t *ctr_local = NULL; -    ctr_heal_ret_val_t ret_val = CTR_CTX_ERROR; -    gf_boolean_t _is_heal_needed = _gf_false; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); - -    /* if the lookup failed lookup don't do anything*/ -    if (op_ret == -1) { -        gf_msg_trace(this->name, 0, "lookup failed with %s", -                     strerror(op_errno)); -        goto out; -    } - -    /* Ignore directory lookups */ -    if (inode->ia_type == IA_IFDIR) { -        goto out; -    } - -    /* if frame local was not set by the ctr_lookup() -     * so don't so anything*/ -    if (!frame->local) { -        goto out; -    } - -    /* if the lookup is for dht link donot record*/ -    if (dht_is_linkfile(buf, dict)) { -        gf_msg_trace(this->name, 0, -                     "Ignoring Lookup " -                     "for dht link file"); -        goto out; -    } - -    ctr_local = frame->local; -    /*Assign the proper inode type*/ -    ctr_local->ia_inode_type = inode->ia_type; - -    /* Copy gfid directly from inode */ -    gf_uuid_copy(CTR_DB_REC(ctr_local).gfid, inode->gfid); - -    /* Checking if gfid and parent gfid is valid */ -    if (gf_uuid_is_null(CTR_DB_REC(ctr_local).gfid) || -        gf_uuid_is_null(CTR_DB_REC(ctr_local).pargfid)) { -        gf_msg_trace(this->name, 0, "Invalid GFID"); -        goto out; -    } - -    /* if its a first entry -     * then mark the ctr_record for create -     * A create will attempt a file and a hard link created in the db*/ -    ctr_xlator_ctx = get_ctr_xlator_ctx(this, inode); -    if (!ctr_xlator_ctx) { -        /* This marks inode heal */ -        CTR_DB_REC(ctr_local).gfdb_fop_type = GFDB_FOP_CREATE_WRITE; -        _is_heal_needed = _gf_true; -    } - -    /* Copy the correct gfid from resolved inode */ -    gf_uuid_copy(CTR_DB_REC(ctr_local).gfid, inode->gfid); - -    /* Add hard link to the list */ -    ret_val = add_hard_link_ctx(frame, this, inode); -    if (ret_val == CTR_CTX_ERROR) { -        gf_msg_trace(this->name, 0, "Failed adding hardlink to list"); -        goto out; -    } -    /* If inode needs healing then heal the hardlink also */ -    else if (ret_val & CTR_TRY_INODE_HEAL) { -        /* This marks inode heal */ -        CTR_DB_REC(ctr_local).gfdb_fop_type = GFDB_FOP_CREATE_WRITE; -        _is_heal_needed = _gf_true; -    } -    /* If hardlink needs healing */ -    else if (ret_val & CTR_TRY_HARDLINK_HEAL) { -        _is_heal_needed = _gf_true; -    } - -    /* If lookup heal needed */ -    if (!_is_heal_needed) -        goto out; - -    /* FINALLY HEAL : Inserts the ctr_db_record populated by ctr_lookup_wind -     * in to the db. It also destroys the frame->local -     * created by ctr_lookup_wind */ -    ret = ctr_lookup_unwind(frame, this); -    if (ret) { -        gf_msg_trace(this->name, 0, "Failed healing/inserting link"); -    } - -out: -    free_ctr_local((gf_ctr_local_t *)frame->local); -    frame->local = NULL; - -    STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, dict, -                        postparent); - -    return 0; -} - -int32_t -ctr_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; -    gf_ctr_link_context_t ctr_link_cx; -    gf_ctr_link_context_t *_link_cx = &ctr_link_cx; -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    GF_ASSERT(frame); -    GF_ASSERT(frame->root); - -    /* Don't handle nameless lookups*/ -    if (!loc->parent || !loc->name) -        goto out; - -    /*fill ctr link context*/ -    FILL_CTR_LINK_CX(_link_cx, loc->parent->gfid, loc->name, out); - -    /* Fill ctr inode context*/ -    /* IA_IFREG : We assume its a file in the wind -     * but in the unwind we are sure what the inode is a file -     * or directory -     * gfid: we are just filling loc->gfid which is not correct. -     * In unwind we fill the correct gfid for successful lookup*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, IA_IFREG, loc->gfid, _link_cx, NULL, -                           GFDB_FOP_DENTRY_WRITE, GFDB_FOP_WIND); - -    /* Create the frame->local and populate ctr_db_record -     * No writing to the db yet */ -    ret = ctr_lookup_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_LINK_WIND_FAILED, -               "Failed to insert link wind"); -    } - -out: -    STACK_WIND(frame, ctr_lookup_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lookup, loc, xdata); -    return 0; -} - -/****************************WRITEV********************************************/ -int32_t -ctr_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -               struct iatt *postbuf, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_WRITEV_UNWIND_FAILED, -               "Failed to insert writev unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, -                        xdata); - -    return 0; -} - -int32_t -ctr_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, -           int32_t count, off_t off, uint32_t flags, struct iobref *iobref, -           dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, fd->inode->ia_type, fd->inode->gfid, NULL, -                           NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_WRITEV_WIND_FAILED, -               "Failed to insert writev wind"); -    } - -out: -    STACK_WIND(frame, ctr_writev_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, -               iobref, xdata); - -    return 0; -} - -/******************************setattr*****************************************/ - -int32_t -ctr_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, struct iatt *preop_stbuf, -                struct iatt *postop_stbuf, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_SETATTR_UNWIND_FAILED, -               "Failed to insert setattr unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, preop_stbuf, -                        postop_stbuf, xdata); - -    return 0; -} - -int32_t -ctr_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, -            int32_t valid, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); -    CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, loc->inode->ia_type, loc->inode->gfid, -                           NULL, NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_SETATTR_WIND_FAILED, -               "Failed to insert setattr wind"); -    } -out: - -    STACK_WIND(frame, ctr_setattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); - -    return 0; -} - -/*************************** fsetattr ***************************************/ -int32_t -ctr_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iatt *preop_stbuf, -                 struct iatt *postop_stbuf, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_SETATTR_UNWIND_FAILED, -               "Failed to insert fsetattr unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(fsetattr, frame, op_ret, op_errno, preop_stbuf, -                        postop_stbuf, xdata); - -    return 0; -} - -int32_t -ctr_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, -             int32_t valid, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); -    CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, fd->inode->ia_type, fd->inode->gfid, NULL, -                           NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_SETATTR_WIND_FAILED, -               "Failed to insert fsetattr wind"); -    } -out: -    STACK_WIND(frame, ctr_fsetattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); - -    return 0; -} -/****************************fremovexattr************************************/ - -int32_t -ctr_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_FREMOVEXATTR_UNWIND_FAILED, -               "Failed to insert fremovexattr unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(fremovexattr, frame, op_ret, op_errno, xdata); - -    return 0; -} - -int32_t -ctr_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, -                 const char *name, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); -    CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, fd->inode->ia_type, fd->inode->gfid, NULL, -                           NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_FREMOVEXATTR_WIND_FAILED, -               "Failed to insert fremovexattr wind"); -    } - -out: -    STACK_WIND(frame, ctr_fremovexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); -    return 0; -} - -/****************************removexattr*************************************/ - -int32_t -ctr_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_REMOVEXATTR_UNWIND_FAILED, -               "Failed to insert removexattr unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(removexattr, frame, op_ret, op_errno, xdata); - -    return 0; -} - -int32_t -ctr_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, -                const char *name, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); -    CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, loc->inode->ia_type, loc->inode->gfid, -                           NULL, NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_REMOVEXATTR_WIND_FAILED, -               "Failed to insert removexattr wind"); -    } - -out: -    STACK_WIND(frame, ctr_removexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); -    return 0; -} - -/****************************truncate****************************************/ - -int32_t -ctr_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                 struct iatt *postbuf, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_TRUNCATE_UNWIND_FAILED, -               "Failed to insert truncate unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf, -                        xdata); - -    return 0; -} - -int32_t -ctr_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, -             dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, loc->inode->ia_type, loc->inode->gfid, -                           NULL, NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_TRUNCATE_WIND_FAILED, -               "Failed to insert truncate wind"); -    } -out: -    STACK_WIND(frame, ctr_truncate_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); -    return 0; -} - -/****************************ftruncate***************************************/ - -int32_t -ctr_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                  struct iatt *postbuf, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_FTRUNCATE_UNWIND_FAILED, -               "Failed to insert ftruncate unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, -                        xdata); - -    return 0; -} - -int32_t -ctr_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -              dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, fd->inode->ia_type, fd->inode->gfid, NULL, -                           NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_INSERT_FTRUNCATE_WIND_FAILED, -               "Failed to insert ftruncate wind"); -    } - -out: -    STACK_WIND(frame, ctr_ftruncate_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); -    return 0; -} - -/****************************rename******************************************/ -int32_t -ctr_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, struct iatt *buf, -               struct iatt *preoldparent, struct iatt *postoldparent, -               struct iatt *prenewparent, struct iatt *postnewparent, -               dict_t *xdata) -{ -    int ret = -1; -    uint32_t remaining_links = -1; -    gf_ctr_local_t *ctr_local = NULL; -    gfdb_fop_type_t fop_type = GFDB_FOP_INVALID_OP; -    gfdb_fop_path_t fop_path = GFDB_FOP_INVALID; - -    GF_ASSERT(frame); -    GF_ASSERT(this); - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_DENTRY_WRITE, -                            GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_RENAME_UNWIND_FAILED, -               "Failed to insert rename unwind"); -        goto out; -    } - -    if (!xdata) -        goto out; -    /* -     * -     * Extracting GF_RESPONSE_LINK_COUNT_XDATA from POSIX Xlator -     * This is only set when we are overwriting hardlinks. -     * -     * */ -    ret = dict_get_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, -                          &remaining_links); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_GET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, -               "Failed to getting GF_RESPONSE_LINK_COUNT_XDATA"); -        remaining_links = -1; -        goto out; -    } - -    ctr_local = frame->local; -    if (!ctr_local) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_NULL_LOCAL, -               "ctr_local is NULL."); -        goto out; -    } - -    /* This is not the only link */ -    if (remaining_links > 1) { -        fop_type = GFDB_FOP_DENTRY_WRITE; -        fop_path = GFDB_FOP_UNDEL; -    } -    /* Last link that was deleted */ -    else if (remaining_links == 1) { -        fop_type = GFDB_FOP_DENTRY_WRITE; -        fop_path = GFDB_FOP_UNDEL_ALL; -    } else { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_RENAME_UNWIND_FAILED, -               "Invalid link count from posix"); -        goto out; -    } - -    ret = ctr_delete_hard_link_from_db( -        this, CTR_DB_REC(ctr_local).old_gfid, CTR_DB_REC(ctr_local).pargfid, -        CTR_DB_REC(ctr_local).file_name, fop_type, fop_path); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_UNLINK_UNWIND_FAILED, -               "Failed to delete records of %s", -               CTR_DB_REC(ctr_local).old_file_name); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, buf, preoldparent, -                        postoldparent, prenewparent, postnewparent, xdata); - -    return 0; -} - -int32_t -ctr_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -           dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; -    gf_ctr_link_context_t new_link_cx, old_link_cx; -    gf_ctr_link_context_t *_nlink_cx = &new_link_cx; -    gf_ctr_link_context_t *_olink_cx = &old_link_cx; -    int is_dict_created = 0; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    /*Fill old link context*/ -    FILL_CTR_LINK_CX(_olink_cx, oldloc->pargfid, oldloc->name, out); - -    /*Fill new link context*/ -    FILL_CTR_LINK_CX(_nlink_cx, newloc->pargfid, newloc->name, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, oldloc->inode->ia_type, -                           oldloc->inode->gfid, _nlink_cx, _olink_cx, -                           GFDB_FOP_DENTRY_WRITE, GFDB_FOP_WIND); - -    /* If the rename is a overwrite of hardlink -     * rename ("file1", "file2") -     * file1 is hardlink for gfid say 00000000-0000-0000-0000-00000000000A -     * file2 is hardlink for gfid say 00000000-0000-0000-0000-00000000000B -     * so we are saving file2 gfid in old_gfid so that we delete entries -     * from the db during rename callback if the fop is successful -     * */ -    if (newloc->inode) { -        /* This is the GFID from where the newloc hardlink will be -         * unlinked */ -        _inode_cx->old_gfid = &newloc->inode->gfid; -    } - -    /* Is a metatdata fop */ -    _inode_cx->is_metadata_fop = _gf_true; - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_RENAME_WIND_FAILED, -               "Failed to insert rename wind"); -    } else { -        /* We are doing updation of hard link in inode context in wind -         * As we don't get the "inode" in the call back for rename */ -        ret = update_hard_link_ctx(frame, this, oldloc->inode); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_UPDATE_HARDLINK_FAILED, -                   "Failed " -                   "updating hard link in ctr inode context"); -            goto out; -        } - -        /* If the newloc has an inode. i.e acquiring hardlink of an -         * exisitng file i.e overwritting a file. -         * */ -        if (newloc->inode) { -            /* Getting the ctr inode context variable for -             * inode whose hardlink will be acquired during -             * the rename -             * */ -            ctr_xlator_ctx = get_ctr_xlator_ctx(this, newloc->inode); -            if (!ctr_xlator_ctx) { -                /* Since there is no ctr inode context -                 * so nothing more to do */ -                ret = 0; -                goto out; -            } - -            /* Deleting hardlink from context variable */ -            ret = ctr_delete_hard_link(this, ctr_xlator_ctx, newloc->pargfid, -                                       newloc->name); -            if (ret) { -                gf_msg(this->name, GF_LOG_ERROR, 0, -                       CTR_MSG_DELETE_HARDLINK_FAILED, -                       "Failed to delete hard link"); -                goto out; -            } - -            /* Requesting for number of hardlinks on the newloc -             * inode from POSIX. -             * */ -            is_dict_created = set_posix_link_request(this, &xdata); -            if (is_dict_created == -1) { -                ret = -1; -                goto out; -            } -        } -    } - -out: -    STACK_WIND(frame, ctr_rename_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); - -    if (is_dict_created == 1) { -        dict_unref(xdata); -    } - -    return 0; -} - -/****************************unlink******************************************/ -int32_t -ctr_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, struct iatt *preparent, -               struct iatt *postparent, dict_t *xdata) -{ -    int ret = -1; -    uint32_t remaining_links = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    if (!xdata) -        goto out; - -    /* -     * -     * Extracting GF_RESPONSE_LINK_COUNT_XDATA from POSIX Xlator -     * -     * */ -    ret = dict_get_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, -                          &remaining_links); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_GET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, -               "Failed to getting GF_RESPONSE_LINK_COUNT_XDATA"); -        remaining_links = -1; -    } - -    /*This is not the only link*/ -    if (remaining_links != 1) { -        ret = ctr_insert_unwind(frame, this, GFDB_FOP_DENTRY_WRITE, -                                GFDB_FOP_UNDEL); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_INSERT_UNLINK_UNWIND_FAILED, -                   "Failed to insert unlink unwind"); -        } -    } -    /*Last link that was deleted*/ -    else if (remaining_links == 1) { -        ret = ctr_insert_unwind(frame, this, GFDB_FOP_DENTRY_WRITE, -                                GFDB_FOP_UNDEL_ALL); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_INSERT_UNLINK_UNWIND_FAILED, -                   "Failed to insert unlink unwind"); -        } -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, -                        xdata); - -    return 0; -} - -int32_t -ctr_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, -           dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; -    gf_ctr_link_context_t ctr_link_cx; -    gf_ctr_link_context_t *_link_cx = &ctr_link_cx; -    gf_boolean_t is_xdata_created = _gf_false; -    struct iatt dummy_stat = {0}; - -    GF_ASSERT(frame); - -    CTR_IS_DISABLED_THEN_GOTO(this, out); - -    /*Fill link context*/ -    FILL_CTR_LINK_CX(_link_cx, loc->pargfid, loc->name, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, loc->inode->ia_type, loc->inode->gfid, -                           _link_cx, NULL, GFDB_FOP_DENTRY_WRITE, -                           GFDB_FOP_WDEL); - -    /*Internal FOP*/ -    _inode_cx->is_internal_fop = is_internal_fop(frame, xdata); - -    /* Is a metadata FOP */ -    _inode_cx->is_metadata_fop = _gf_true; - -    /* If its a internal FOP and dht link file donot record*/ -    if (_inode_cx->is_internal_fop && dht_is_linkfile(&dummy_stat, xdata)) { -        goto out; -    } - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_UNLINK_UNWIND_FAILED, -               "Failed to insert unlink wind"); -    } else { -        /* We are doing delete of hard link in inode context in wind -         * As we don't get the "inode" in the call back for rename */ -        ret = delete_hard_link_ctx(frame, this, loc->inode); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_DELETE_HARDLINK_FAILED, -                   "Failed " -                   "deleting hard link from ctr inode context"); -        } -    } - -    /* -     * -     * Sending GF_REQUEST_LINK_COUNT_XDATA -     * to POSIX Xlator to send link count in unwind path -     * -     * */ -    /*create xdata if NULL*/ -    if (!xdata) { -        xdata = dict_new(); -        is_xdata_created = (xdata) ? _gf_true : _gf_false; -    } -    if (!xdata) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_XDATA_NULL, -               "xdata is NULL :Cannot send " -               "GF_REQUEST_LINK_COUNT_XDATA to posix"); -        goto out; -    } - -    ret = dict_set_int32(xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_SET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, -               "Failed setting GF_REQUEST_LINK_COUNT_XDATA"); -        if (is_xdata_created) { -            dict_unref(xdata); -        } -        goto out; -    } - -out: -    STACK_WIND(frame, ctr_unlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); - -    if (is_xdata_created) -        dict_unref(xdata); - -    return 0; -} - -/****************************fsync******************************************/ -int32_t -ctr_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, -              dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_FSYNC_UNWIND_FAILED, -               "Failed to insert fsync unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); - -    return 0; -} - -int32_t -ctr_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, -          dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, fd->inode->ia_type, fd->inode->gfid, NULL, -                           NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_FSYNC_WIND_FAILED, -               "Failed to insert fsync wind"); -    } - -out: -    STACK_WIND(frame, ctr_fsync_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); -    return 0; -} - -/****************************setxattr****************************************/ - -int -ctr_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_FSYNC_UNWIND_FAILED, -               "Failed to insert setxattr unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); - -    return 0; -} - -int -ctr_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr, -             int flags, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); -    CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, loc->inode->ia_type, loc->inode->gfid, -                           NULL, NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_SETATTR_WIND_FAILED, -               "Failed to insert setxattr wind"); -    } - -out: -    STACK_WIND(frame, ctr_setxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->setxattr, loc, xattr, flags, xdata); -    return 0; -} -/**************************** fsetxattr *************************************/ -int32_t -ctr_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_WRITE, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_FSYNC_UNWIND_FAILED, -               "Failed to insert fsetxattr unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); - -    return 0; -} - -int32_t -ctr_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, -              int32_t flags, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); -    CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, fd->inode->ia_type, fd->inode->gfid, NULL, -                           NULL, GFDB_FOP_INODE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_SETATTR_WIND_FAILED, -               "Failed to insert fsetxattr wind"); -    } - -out: -    STACK_WIND(frame, ctr_fsetxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); -    return 0; -} -/****************************mknod*******************************************/ - -int32_t -ctr_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, inode_t *inode, struct iatt *buf, -              struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    int ret = -1; -    ctr_heal_ret_val_t ret_val = CTR_CTX_ERROR; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    /* Add hard link to the list */ -    ret_val = add_hard_link_ctx(frame, this, inode); -    if (ret_val == CTR_CTX_ERROR) { -        gf_msg_trace(this->name, 0, "Failed adding hard link"); -    } - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_CREATE_WRITE, -                            GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_MKNOD_UNWIND_FAILED, -               "Failed to insert mknod unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(mknod, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); - -    return 0; -} - -int -ctr_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, -          dev_t rdev, mode_t umask, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; -    gf_ctr_link_context_t ctr_link_cx; -    gf_ctr_link_context_t *_link_cx = &ctr_link_cx; -    uuid_t gfid = { -        0, -    }; -    uuid_t *ptr_gfid = &gfid; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    GF_ASSERT(frame); -    GF_ASSERT(frame->root); - -    /*get gfid from xdata dict*/ -    ret = dict_get_gfuuid(xdata, "gfid-req", &gfid); -    if (ret) { -        gf_msg_debug(this->name, 0, "failed to get gfid from dict"); -        goto out; -    } - -    /*fill ctr link context*/ -    FILL_CTR_LINK_CX(_link_cx, loc->pargfid, loc->name, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, loc->inode->ia_type, *ptr_gfid, _link_cx, -                           NULL, GFDB_FOP_CREATE_WRITE, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_MKNOD_WIND_FAILED, -               "Failed to insert mknod wind"); -    } - -out: -    STACK_WIND(frame, ctr_mknod_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); -    return 0; -} - -/****************************create******************************************/ -int -ctr_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -               int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, -               struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = add_hard_link_ctx(frame, this, inode); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_ADD_HARDLINK_FAILED, -               "Failed adding hard link"); -    } - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_CREATE_WRITE, -                            GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_CREATE_UNWIND_FAILED, -               "Failed to insert create unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, stbuf, -                        preparent, postparent, xdata); - -    return 0; -} - -int -ctr_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -           mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; -    gf_ctr_link_context_t ctr_link_cx; -    gf_ctr_link_context_t *_link_cx = &ctr_link_cx; -    uuid_t gfid = { -        0, -    }; -    uuid_t *ptr_gfid = &gfid; -    struct iatt dummy_stat = {0}; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); - -    GF_ASSERT(frame); -    GF_ASSERT(frame->root); - -    /*Get GFID from Xdata dict*/ -    ret = dict_get_gfuuid(xdata, "gfid-req", &gfid); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_GET_GFID_FROM_DICT_FAILED, -               "failed to get gfid from dict"); -        goto out; -    } - -    /*fill ctr link context*/ -    FILL_CTR_LINK_CX(_link_cx, loc->pargfid, loc->name, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, loc->inode->ia_type, *ptr_gfid, _link_cx, -                           NULL, GFDB_FOP_CREATE_WRITE, GFDB_FOP_WIND); - -    /*Internal FOP*/ -    _inode_cx->is_internal_fop = is_internal_fop(frame, xdata); - -    /* If its a internal FOP and dht link file donot record*/ -    if (_inode_cx->is_internal_fop && dht_is_linkfile(&dummy_stat, xdata)) { -        goto out; -    } - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, &ctr_inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_CREATE_WIND_FAILED, -               "Failed to insert create wind"); -    } -out: -    STACK_WIND(frame, ctr_create_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, -               xdata); -    return 0; -} - -/****************************link********************************************/ - -int -ctr_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -             int op_errno, inode_t *inode, struct iatt *stbuf, -             struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    /* Add hard link to the list */ -    ret = add_hard_link_ctx(frame, this, inode); -    if (ret) { -        gf_msg_trace(this->name, 0, "Failed adding hard link"); -    } - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_DENTRY_WRITE, -                            GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_CREATE_UNWIND_FAILED, -               "Failed to insert create unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(link, frame, op_ret, op_errno, inode, stbuf, preparent, -                        postparent, xdata); -    return 0; -} - -int -ctr_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -         dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; -    gf_ctr_link_context_t ctr_link_cx; -    gf_ctr_link_context_t *_link_cx = &ctr_link_cx; -    struct iatt dummy_stat = {0}; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); - -    GF_ASSERT(frame); -    GF_ASSERT(frame->root); - -    /*fill ctr link context*/ -    FILL_CTR_LINK_CX(_link_cx, newloc->pargfid, newloc->name, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, oldloc->inode->ia_type, -                           oldloc->inode->gfid, _link_cx, NULL, -                           GFDB_FOP_DENTRY_WRITE, GFDB_FOP_WIND); - -    /*Internal FOP*/ -    _inode_cx->is_internal_fop = is_internal_fop(frame, xdata); - -    /* Is a metadata fop */ -    _inode_cx->is_metadata_fop = _gf_true; - -    /* If its a internal FOP and dht link file donot record*/ -    if (_inode_cx->is_internal_fop && dht_is_linkfile(&dummy_stat, xdata)) { -        goto out; -    } - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_LINK_WIND_FAILED, -               "Failed to insert link wind"); -    } - -out: -    STACK_WIND(frame, ctr_link_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); -    return 0; -} - -/******************************readv*****************************************/ -int -ctr_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -              int op_errno, struct iovec *vector, int count, struct iatt *stbuf, -              struct iobref *iobref, dict_t *xdata) -{ -    int ret = -1; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, out); - -    ret = ctr_insert_unwind(frame, this, GFDB_FOP_INODE_READ, GFDB_FOP_UNWIND); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_CREATE_UNWIND_FAILED, -               "Failed to insert create unwind"); -    } - -out: -    ctr_free_frame_local(frame); - -    STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf, -                        iobref, xdata); -    return 0; -} - -int -ctr_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, -          uint32_t flags, dict_t *xdata) -{ -    int ret = -1; -    gf_ctr_inode_context_t ctr_inode_cx; -    gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx; - -    CTR_IS_DISABLED_THEN_GOTO(this, out); -    CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, out); - -    /*Fill ctr inode context*/ -    FILL_CTR_INODE_CONTEXT(_inode_cx, fd->inode->ia_type, fd->inode->gfid, NULL, -                           NULL, GFDB_FOP_INODE_READ, GFDB_FOP_WIND); - -    /*record into the database*/ -    ret = ctr_insert_wind(frame, this, _inode_cx); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_READV_WIND_FAILED, -               "Failed to insert readv wind"); -    } - -out: -    STACK_WIND(frame, ctr_readv_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readv, fd, size, off, flags, xdata); -    return 0; -} - -/*******************************ctr_ipc****************************************/ - -/*This is the call back function per record/file from data base*/ -static int -ctr_db_query_callback(gfdb_query_record_t *gfdb_query_record, void *args) -{ -    int ret = -1; -    ctr_query_cbk_args_t *query_cbk_args = args; - -    GF_VALIDATE_OR_GOTO("ctr", query_cbk_args, out); - -    ret = gfdb_write_query_record(query_cbk_args->query_fd, gfdb_query_record); -    if (ret) { -        gf_msg("ctr", GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "Failed to write to query file"); -        goto out; -    } - -    query_cbk_args->count++; - -    ret = 0; -out: -    return ret; -} - -/* This function does all the db queries related to tiering and - * generates/populates new/existing query file - * inputs: - * xlator_t *this : CTR Translator - * void *conn_node : Database connection - * char *query_file: the query file that needs to be updated - * gfdb_ipc_ctr_params_t *ipc_ctr_params: the query parameters - * Return: - * On success 0 - * On failure -1 - * */ -int -ctr_db_query(xlator_t *this, void *conn_node, char *query_file, -             gfdb_ipc_ctr_params_t *ipc_ctr_params) -{ -    int ret = -1; -    ctr_query_cbk_args_t query_cbk_args = {0}; - -    GF_VALIDATE_OR_GOTO("ctr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, conn_node, out); -    GF_VALIDATE_OR_GOTO(this->name, query_file, out); -    GF_VALIDATE_OR_GOTO(this->name, ipc_ctr_params, out); - -    /*Query for eligible files from db*/ -    query_cbk_args.query_fd = open(query_file, O_WRONLY | O_CREAT | O_APPEND, -                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -    if (query_cbk_args.query_fd < 0) { -        gf_msg(this->name, GF_LOG_ERROR, errno, CTR_MSG_FATAL_ERROR, -               "Failed to open query file %s", query_file); -        goto out; -    } -    if (!ipc_ctr_params->is_promote) { -        if (ipc_ctr_params->emergency_demote) { -            /* emergency demotion mode */ -            ret = find_all(conn_node, ctr_db_query_callback, -                           (void *)&query_cbk_args, -                           ipc_ctr_params->query_limit); -        } else { -            if (ipc_ctr_params->write_freq_threshold == 0 && -                ipc_ctr_params->read_freq_threshold == 0) { -                ret = find_unchanged_for_time(conn_node, ctr_db_query_callback, -                                              (void *)&query_cbk_args, -                                              &ipc_ctr_params->time_stamp); -            } else { -                ret = find_unchanged_for_time_freq( -                    conn_node, ctr_db_query_callback, (void *)&query_cbk_args, -                    &ipc_ctr_params->time_stamp, -                    ipc_ctr_params->write_freq_threshold, -                    ipc_ctr_params->read_freq_threshold, _gf_false); -            } -        } -    } else { -        if (ipc_ctr_params->write_freq_threshold == 0 && -            ipc_ctr_params->read_freq_threshold == 0) { -            ret = find_recently_changed_files(conn_node, ctr_db_query_callback, -                                              (void *)&query_cbk_args, -                                              &ipc_ctr_params->time_stamp); -        } else { -            ret = find_recently_changed_files_freq( -                conn_node, ctr_db_query_callback, (void *)&query_cbk_args, -                &ipc_ctr_params->time_stamp, -                ipc_ctr_params->write_freq_threshold, -                ipc_ctr_params->read_freq_threshold, _gf_false); -        } -    } -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "FATAL: query from db failed"); -        goto out; -    } - -    ret = clear_files_heat(conn_node); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "FATAL: Failed to clear db entries"); -        goto out; -    } - -    ret = 0; -out: - -    if (!ret) -        ret = query_cbk_args.count; - -    if (query_cbk_args.query_fd >= 0) { -        sys_close(query_cbk_args.query_fd); -        query_cbk_args.query_fd = -1; -    } - -    return ret; -} - -void * -ctr_compact_thread(void *args) -{ -    int ret = -1; -    void *db_conn = NULL; - -    xlator_t *this = NULL; -    gf_ctr_private_t *priv = NULL; -    gf_boolean_t compact_active = _gf_false; -    gf_boolean_t compact_mode_switched = _gf_false; - -    this = (xlator_t *)args; - -    GF_VALIDATE_OR_GOTO("ctr", this, out); - -    priv = this->private; - -    db_conn = priv->_db_conn; -    compact_active = priv->compact_active; -    compact_mode_switched = priv->compact_mode_switched; - -    gf_msg("ctr-compact", GF_LOG_INFO, 0, CTR_MSG_SET, "Starting compaction"); - -    ret = compact_db(db_conn, compact_active, compact_mode_switched); - -    if (ret) { -        gf_msg("ctr-compact", GF_LOG_ERROR, 0, CTR_MSG_SET, -               "Failed to perform the compaction"); -    } - -    ret = pthread_mutex_lock(&priv->compact_lock); - -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -               "Failed to acquire lock"); -        goto out; -    } - -    /* We are done compaction on this brick. Set all flags to false */ -    priv->compact_active = _gf_false; -    priv->compact_mode_switched = _gf_false; - -    ret = pthread_mutex_unlock(&priv->compact_lock); - -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -               "Failed to release lock"); -        goto out; -    } - -out: -    return NULL; -} - -int -ctr_ipc_helper(xlator_t *this, dict_t *in_dict, dict_t *out_dict) -{ -    int ret = -1; -    char *ctr_ipc_ops = NULL; -    gf_ctr_private_t *priv = NULL; -    char *db_version = NULL; -    char *db_param_key = NULL; -    char *db_param = NULL; -    char *query_file = NULL; -    gfdb_ipc_ctr_params_t *ipc_ctr_params = NULL; -    int result = 0; -    pthread_t compact_thread; - -    GF_VALIDATE_OR_GOTO("ctr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, this->private, out); -    priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, priv->_db_conn, out); -    GF_VALIDATE_OR_GOTO(this->name, in_dict, out); -    GF_VALIDATE_OR_GOTO(this->name, out_dict, out); - -    GET_DB_PARAM_FROM_DICT(this->name, in_dict, GFDB_IPC_CTR_KEY, ctr_ipc_ops, -                           out); - -    /*if its a db clear operation */ -    if (strncmp(ctr_ipc_ops, GFDB_IPC_CTR_CLEAR_OPS, -                SLEN(GFDB_IPC_CTR_CLEAR_OPS)) == 0) { -        ret = clear_files_heat(priv->_db_conn); -        if (ret) -            goto out; - -    } /* if its a query operation, in  which case its query + clear db*/ -    else if (strncmp(ctr_ipc_ops, GFDB_IPC_CTR_QUERY_OPS, -                     SLEN(GFDB_IPC_CTR_QUERY_OPS)) == 0) { -        ret = dict_get_str(in_dict, GFDB_IPC_CTR_GET_QFILE_PATH, &query_file); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed extracting query file path"); -            goto out; -        } - -        ret = dict_get_bin(in_dict, GFDB_IPC_CTR_GET_QUERY_PARAMS, -                           (void *)&ipc_ctr_params); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed extracting query parameters"); -            goto out; -        } - -        ret = ctr_db_query(this, priv->_db_conn, query_file, ipc_ctr_params); - -        ret = dict_set_int32(out_dict, GFDB_IPC_CTR_RET_QUERY_COUNT, ret); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed setting query reply"); -            goto out; -        } - -    } /* if its a query for db version */ -    else if (strncmp(ctr_ipc_ops, GFDB_IPC_CTR_GET_DB_VERSION_OPS, -                     SLEN(GFDB_IPC_CTR_GET_DB_VERSION_OPS)) == 0) { -        ret = get_db_version(priv->_db_conn, &db_version); -        if (ret == -1 || !db_version) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed extracting db version "); -            goto out; -        } - -        SET_DB_PARAM_TO_DICT(this->name, out_dict, GFDB_IPC_CTR_RET_DB_VERSION, -                             db_version, ret, error); - -    } /* if its a query for a db setting */ -    else if (strncmp(ctr_ipc_ops, GFDB_IPC_CTR_GET_DB_PARAM_OPS, -                     SLEN(GFDB_IPC_CTR_GET_DB_PARAM_OPS)) == 0) { -        ret = dict_get_str(in_dict, GFDB_IPC_CTR_GET_DB_KEY, &db_param_key); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed extracting db param key"); -            goto out; -        } - -        ret = get_db_params(priv->_db_conn, db_param_key, &db_param); -        if (ret == -1 || !db_param) { -            goto out; -        } - -        SET_DB_PARAM_TO_DICT(this->name, out_dict, db_param_key, db_param, ret, -                             error); -    } /* if its an attempt to compact the database */ -    else if (strncmp(ctr_ipc_ops, GFDB_IPC_CTR_SET_COMPACT_PRAGMA, -                     SLEN(GFDB_IPC_CTR_SET_COMPACT_PRAGMA)) == 0) { -        ret = pthread_mutex_lock(&priv->compact_lock); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed to acquire lock for compaction"); -            goto out; -        } - -        if ((priv->compact_active || priv->compact_mode_switched)) { -            /* Compaction in progress. LEAVE */ -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Compaction already in progress."); -            pthread_mutex_unlock(&priv->compact_lock); -            goto out; -        } -        /* At this point, we should be the only one on the brick */ -        /* compacting */ - -        /* Grab the arguments from the dictionary */ -        ret = dict_get_int32(in_dict, "compact_active", &result); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed to get compaction type"); -            goto out; -        } - -        if (result) { -            priv->compact_active = _gf_true; -        } - -        ret = dict_get_int32(in_dict, "compact_mode_switched", &result); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed to see if compaction switched"); -            goto out; -        } - -        if (result) { -            priv->compact_mode_switched = _gf_true; -            gf_msg("ctr-compact", GF_LOG_TRACE, 0, CTR_MSG_SET, -                   "Pre-thread: Compact mode switch is true"); -        } else { -            gf_msg("ctr-compact", GF_LOG_TRACE, 0, CTR_MSG_SET, -                   "Pre-thread: Compact mode switch is false"); -        } - -        ret = pthread_mutex_unlock(&priv->compact_lock); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed to release lock for compaction"); -            goto out; -        } - -        ret = gf_thread_create(&compact_thread, NULL, ctr_compact_thread, -                               (void *)this, "ctrcomp"); - -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -                   "Failed to spawn compaction thread"); -            goto out; -        } - -        goto out; -    } /* default case */ -    else { -        goto out; -    } - -    ret = 0; -    goto out; -error: -    GF_FREE(db_param_key); -    GF_FREE(db_param); -    GF_FREE(db_version); -out: -    return ret; -} - -/* IPC Call from tier migrator to clear the heat on the DB */ -int32_t -ctr_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *in_dict) -{ -    int ret = -1; -    gf_ctr_private_t *priv = NULL; -    dict_t *out_dict = NULL; - -    GF_ASSERT(this); -    priv = this->private; -    GF_ASSERT(priv); -    GF_ASSERT(priv->_db_conn); -    GF_VALIDATE_OR_GOTO(this->name, in_dict, wind); - -    if (op != GF_IPC_TARGET_CTR) -        goto wind; - -    out_dict = dict_new(); -    if (!out_dict) { -        goto out; -    } - -    ret = ctr_ipc_helper(this, in_dict, out_dict); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, -               "Failed in ctr_ipc_helper"); -    } -out: - -    STACK_UNWIND_STRICT(ipc, frame, ret, 0, out_dict); - -    if (out_dict) -        dict_unref(out_dict); - -    return 0; - -wind: -    STACK_WIND(frame, default_ipc_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->ipc, op, in_dict); - -    return 0; -} - -/* Call to initialize db for ctr xlator while ctr is enabled */ -int32_t -initialize_ctr_resource(xlator_t *this, gf_ctr_private_t *priv) -{ -    int ret_db = -1; -    dict_t *params_dict = NULL; - -    if (!priv) -        goto error; - -    /* For compaction */ -    priv->compact_active = _gf_false; -    priv->compact_mode_switched = _gf_false; -    ret_db = pthread_mutex_init(&priv->compact_lock, NULL); - -    if (ret_db) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "FATAL: Failed initializing compaction mutex"); -        goto error; -    } - -    params_dict = dict_new(); -    if (!params_dict) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INIT_DB_PARAMS_FAILED, -               "DB Params cannot initialized!"); -        goto error; -    } - -    /*Extract db params options*/ -    ret_db = extract_db_params(this, params_dict, priv->gfdb_db_type); -    if (ret_db) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_EXTRACT_DB_PARAM_OPTIONS_FAILED, -               "Failed extracting db params options"); -        goto error; -    } - -    /*Create a memory pool for ctr xlator*/ -    this->local_pool = mem_pool_new(gf_ctr_local_t, 64); -    if (!this->local_pool) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_CREATE_LOCAL_MEMORY_POOL_FAILED, -               "failed to create local memory pool"); -        goto error; -    } - -    /*Initialize Database Connection*/ -    priv->_db_conn = init_db(params_dict, priv->gfdb_db_type); -    if (!priv->_db_conn) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "FATAL: Failed initializing data base"); -        goto error; -    } - -    ret_db = 0; -    goto out; - -error: -    if (this) -        mem_pool_destroy(this->local_pool); - -    if (priv) { -        GF_FREE(priv->ctr_db_path); -    } -    GF_FREE(priv); -    ret_db = -1; -out: -    if (params_dict) -        dict_unref(params_dict); - -    return ret_db; -} - -/******************************************************************************/ -int -reconfigure(xlator_t *this, dict_t *options) -{ -    char *temp_str = NULL; -    int ret = 0; -    gf_ctr_private_t *priv = NULL; - -    priv = this->private; - -    if (dict_get_str(options, "changetimerecorder.frequency", &temp_str)) { -        gf_msg(this->name, GF_LOG_TRACE, 0, CTR_MSG_SET, "set"); -    } - -    GF_OPTION_RECONF("ctr-enabled", priv->enabled, options, bool, out); -    if (!priv->enabled) { -        gf_msg(GFDB_DATA_STORE, GF_LOG_INFO, 0, CTR_MSG_XLATOR_DISABLED, -               "CTR Xlator is not enabled so skip ctr reconfigure"); -        goto out; -    } - -    /* If ctr is enabled after skip init for ctr xlator then call -       initialize_ctr_resource during reconfigure phase to allocate resources -       for xlator -    */ -    if (priv->enabled && !priv->_db_conn) { -        ret = initialize_ctr_resource(this, priv); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -                   "FATAL: Failed ctr initialize resource"); -            goto out; -        } -    } - -    GF_OPTION_RECONF("record-counters", priv->ctr_record_counter, options, bool, -                     out); - -    GF_OPTION_RECONF("ctr-record-metadata-heat", priv->ctr_record_metadata_heat, -                     options, bool, out); - -    GF_OPTION_RECONF("ctr_link_consistency", priv->ctr_link_consistency, -                     options, bool, out); - -    GF_OPTION_RECONF("ctr_lookupheal_inode_timeout", -                     priv->ctr_lookupheal_inode_timeout, options, uint64, out); - -    GF_OPTION_RECONF("ctr_lookupheal_link_timeout", -                     priv->ctr_lookupheal_link_timeout, options, uint64, out); - -    GF_OPTION_RECONF("record-exit", priv->ctr_record_unwind, options, bool, -                     out); - -    GF_OPTION_RECONF("record-entry", priv->ctr_record_wind, options, bool, out); - -    /* If database is sqlite */ -    if (priv->gfdb_db_type == GFDB_SQLITE3) { -        /* AUTOCHECKPOINT */ -        if (dict_get_str(options, GFDB_SQL_PARAM_WAL_AUTOCHECK, &temp_str) == -            0) { -            ret = set_db_params(priv->_db_conn, "wal_autocheckpoint", temp_str); -            if (ret) { -                gf_msg(this->name, GF_LOG_ERROR, 0, -                       CTR_MSG_SET_VALUE_TO_SQL_PARAM_FAILED, -                       "Failed  to set %s", GFDB_SQL_PARAM_WAL_AUTOCHECK); -            } -        } - -        /* CACHE_SIZE */ -        if (dict_get_str(options, GFDB_SQL_PARAM_CACHE_SIZE, &temp_str) == 0) { -            ret = set_db_params(priv->_db_conn, "cache_size", temp_str); -            if (ret) { -                gf_msg(this->name, GF_LOG_ERROR, 0, -                       CTR_MSG_SET_VALUE_TO_SQL_PARAM_FAILED, -                       "Failed  to set %s", GFDB_SQL_PARAM_CACHE_SIZE); -            } -        } -    } - -    ret = 0; - -out: - -    return ret; -} - -/****************************init********************************************/ - -int32_t -init(xlator_t *this) -{ -    gf_ctr_private_t *priv = NULL; -    int ret_db = -1; - -    if (!this) { -        gf_msg("ctr", GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "FATAL: ctr this is not initialized"); -        return -1; -    } - -    if (!this->children || this->children->next) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "FATAL: ctr should have exactly one child"); -        return -1; -    } - -    if (!this->parents) { -        gf_msg(this->name, GF_LOG_WARNING, 0, CTR_MSG_DANGLING_VOLUME, -               "dangling volume. check volfile "); -    } - -    priv = GF_CALLOC(1, sizeof(*priv), gf_ctr_mt_private_t); -    if (!priv) { -        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, CTR_MSG_CALLOC_FAILED, -               "Calloc did not work!!!"); -        return -1; -    } - -    /*Default values for the translator*/ -    priv->ctr_record_wind = _gf_true; -    priv->ctr_record_unwind = _gf_false; -    priv->ctr_hot_brick = _gf_false; -    priv->gfdb_db_type = GFDB_SQLITE3; -    priv->gfdb_sync_type = GFDB_DB_SYNC; -    priv->_db_conn = NULL; -    priv->ctr_lookupheal_link_timeout = CTR_DEFAULT_HARDLINK_EXP_PERIOD; -    priv->ctr_lookupheal_inode_timeout = CTR_DEFAULT_INODE_EXP_PERIOD; - -    /*Extract ctr xlator options*/ -    ret_db = extract_ctr_options(this, priv); -    if (ret_db) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_EXTRACT_CTR_XLATOR_OPTIONS_FAILED, -               "Failed extracting ctr xlator options"); -        GF_FREE(priv); -        return -1; -    } - -    if (!priv->enabled) { -        gf_msg(GFDB_DATA_STORE, GF_LOG_INFO, 0, CTR_MSG_XLATOR_DISABLED, -               "CTR Xlator is not enabled so skip ctr init"); -        goto out; -    } - -    ret_db = initialize_ctr_resource(this, priv); -    if (ret_db) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_FATAL_ERROR, -               "FATAL: Failed ctr initialize resource"); -        return -1; -    } - -out: -    this->private = (void *)priv; -    return 0; -} - -int -notify(xlator_t *this, int event, void *data, ...) -{ -    gf_ctr_private_t *priv = NULL; -    int ret = 0; - -    priv = this->private; - -    if (!priv) -        goto out; - -    ret = default_notify(this, event, data); - -out: -    return ret; -} - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    GF_VALIDATE_OR_GOTO("ctr", this, out); - -    ret = xlator_mem_acct_init(this, gf_ctr_mt_end + 1); - -    if (ret != 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_MEM_ACC_INIT_FAILED, -               "Memory accounting init" -               "failed"); -        return ret; -    } -out: -    return ret; -} - -void -fini(xlator_t *this) -{ -    gf_ctr_private_t *priv = NULL; - -    priv = this->private; - -    if (priv && priv->enabled) { -        if (fini_db(priv->_db_conn)) { -            gf_msg(this->name, GF_LOG_WARNING, 0, CTR_MSG_CLOSE_DB_CONN_FAILED, -                   "Failed closing " -                   "db connection"); -        } - -        if (priv->_db_conn) -            priv->_db_conn = NULL; - -        GF_FREE(priv->ctr_db_path); -        if (pthread_mutex_destroy(&priv->compact_lock)) { -            gf_msg(this->name, GF_LOG_WARNING, 0, CTR_MSG_CLOSE_DB_CONN_FAILED, -                   "Failed to " -                   "destroy the compaction mutex"); -        } -    } -    GF_FREE(priv); -    mem_pool_destroy(this->local_pool); -    this->local_pool = NULL; - -    return; -} - -struct xlator_fops fops = { -    /*lookup*/ -    .lookup = ctr_lookup, -    /*write fops */ -    .mknod = ctr_mknod, -    .create = ctr_create, -    .truncate = ctr_truncate, -    .ftruncate = ctr_ftruncate, -    .setxattr = ctr_setxattr, -    .fsetxattr = ctr_fsetxattr, -    .removexattr = ctr_removexattr, -    .fremovexattr = ctr_fremovexattr, -    .unlink = ctr_unlink, -    .link = ctr_link, -    .rename = ctr_rename, -    .writev = ctr_writev, -    .setattr = ctr_setattr, -    .fsetattr = ctr_fsetattr, -    /*read fops*/ -    .readv = ctr_readv, -    /* IPC call*/ -    .ipc = ctr_ipc}; - -struct xlator_cbks cbks = {.forget = ctr_forget}; - -struct volume_options options[] = { -    {.key = -         { -             "ctr-enabled", -         }, -     .type = GF_OPTION_TYPE_BOOL, -     .value = {"on", "off"}, -     .default_value = "off", -     .description = "Enables the CTR", -     .flags = OPT_FLAG_SETTABLE}, -    {.key = {"record-entry"}, -     .type = GF_OPTION_TYPE_BOOL, -     .value = {"on", "off"}, -     .default_value = "on"}, -    {.key = {"record-exit"}, -     .type = GF_OPTION_TYPE_BOOL, -     .value = {"on", "off"}, -     .default_value = "off"}, -    {.key = {"record-counters"}, -     .type = GF_OPTION_TYPE_BOOL, -     .value = {"on", "off"}, -     .default_value = "off", -     .op_version = {GD_OP_VERSION_3_7_0}, -     .flags = OPT_FLAG_SETTABLE, -     .tags = {}}, -    {.key = {"ctr-record-metadata-heat"}, -     .type = GF_OPTION_TYPE_BOOL, -     .value = {"on", "off"}, -     .default_value = "off", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_0}, -     .tags = {}}, -    {.key = {"ctr_link_consistency"}, -     .type = GF_OPTION_TYPE_BOOL, -     .value = {"on", "off"}, -     .default_value = "off", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_0}, -     .tags = {}}, -    {.key = {"ctr_lookupheal_link_timeout"}, -     .type = GF_OPTION_TYPE_INT, -     .default_value = "300", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_2}, -     .tags = {}}, -    {.key = {"ctr_lookupheal_inode_timeout"}, -     .type = GF_OPTION_TYPE_INT, -     .default_value = "300", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_2}, -     .tags = {}}, -    {.key = {"hot-brick"}, -     .type = GF_OPTION_TYPE_BOOL, -     .value = {"on", "off"}, -     .default_value = "off"}, -    {.key = {"db-type"}, -     .type = GF_OPTION_TYPE_STR, -     .value = {"hashfile", "rocksdb", "changelog", "sqlite3", "hyperdex"}, -     .default_value = "sqlite3", -     .op_version = {GD_OP_VERSION_3_7_0}, -     .flags = OPT_FLAG_SETTABLE, -     .tags = {}}, -    {.key = {"db-sync"}, -     .type = GF_OPTION_TYPE_STR, -     .value = {"sync", "async"}, -     .default_value = "sync"}, -    {.key = {"db-path"}, .type = GF_OPTION_TYPE_PATH}, -    {.key = {"db-name"}, .type = GF_OPTION_TYPE_STR}, -    {.key = {GFDB_SQL_PARAM_SYNC}, -     .type = GF_OPTION_TYPE_STR, -     .value = {"off", "normal", "full"}, -     .default_value = "normal"}, -    {.key = {GFDB_SQL_PARAM_JOURNAL_MODE}, -     .type = GF_OPTION_TYPE_STR, -     .value = {"delete", "truncate", "persist", "memory", "wal", "off"}, -     .default_value = "wal", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_0}, -     .tags = {}}, -    {.key = {GFDB_SQL_PARAM_AUTO_VACUUM}, -     .type = GF_OPTION_TYPE_STR, -     .value = {"off", "full", "incr"}, -     .default_value = "off", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_0}, -     .tags = {}}, -    {.key = {GFDB_SQL_PARAM_WAL_AUTOCHECK}, -     .type = GF_OPTION_TYPE_INT, -     .default_value = "25000", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_0}, -     .tags = {}}, -    {.key = {GFDB_SQL_PARAM_CACHE_SIZE}, -     .type = GF_OPTION_TYPE_INT, -     .default_value = "12500", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_0}, -     .tags = {}}, -    {.key = {GFDB_SQL_PARAM_PAGE_SIZE}, -     .type = GF_OPTION_TYPE_INT, -     .default_value = "4096", -     .flags = OPT_FLAG_SETTABLE, -     .op_version = {GD_OP_VERSION_3_7_0}, -     .tags = {}}, -    {.key = {NULL}}, -}; diff --git a/xlators/features/changetimerecorder/src/changetimerecorder.h b/xlators/features/changetimerecorder/src/changetimerecorder.h deleted file mode 100644 index 0150a1c91bc..00000000000 --- a/xlators/features/changetimerecorder/src/changetimerecorder.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -   Copyright (c) 2006-2015 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#ifndef __CTR_H -#define __CTR_H - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/common-utils.h> -#include "ctr_mem_types.h" -#include "ctr-helper.h" - -#endif /* __CTR_H */ diff --git a/xlators/features/changetimerecorder/src/ctr-helper.c b/xlators/features/changetimerecorder/src/ctr-helper.c deleted file mode 100644 index e1e65735cef..00000000000 --- a/xlators/features/changetimerecorder/src/ctr-helper.c +++ /dev/null @@ -1,293 +0,0 @@ -/* -   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#include "gfdb_sqlite3.h" -#include "ctr-helper.h" -#include "ctr-messages.h" - -/******************************************************************************* - * - *                      Fill unwind into db record - * - ******************************************************************************/ -int -fill_db_record_for_unwind(xlator_t *this, gf_ctr_local_t *ctr_local, -                          gfdb_fop_type_t fop_type, gfdb_fop_path_t fop_path) -{ -    int ret = -1; -    gfdb_time_t *ctr_uwtime = NULL; -    gf_ctr_private_t *_priv = NULL; - -    GF_ASSERT(this); -    _priv = this->private; -    GF_ASSERT(_priv); - -    GF_ASSERT(ctr_local); - -    /*If not unwind path error*/ -    if (!isunwindpath(fop_path)) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_WRONG_FOP_PATH, -               "Wrong fop_path. Should be unwind"); -        goto out; -    } - -    ctr_uwtime = &CTR_DB_REC(ctr_local).gfdb_unwind_change_time; -    CTR_DB_REC(ctr_local).gfdb_fop_path = fop_path; -    CTR_DB_REC(ctr_local).gfdb_fop_type = fop_type; - -    ret = gettimeofday(ctr_uwtime, NULL); -    if (ret == -1) { -        gf_msg(this->name, GF_LOG_ERROR, errno, -               CTR_MSG_FILL_UNWIND_TIME_REC_ERROR, -               "Error " -               "filling unwind time record %s", -               strerror(errno)); -        goto out; -    } - -    /* Special case i.e if its a tier rebalance -     * + cold tier brick -     * + its a create/mknod FOP -     * we record unwind time as zero */ -    if (ctr_local->client_pid == GF_CLIENT_PID_TIER_DEFRAG && -        (!_priv->ctr_hot_brick) && isdentrycreatefop(fop_type)) { -        memset(ctr_uwtime, 0, sizeof(*ctr_uwtime)); -    } -    ret = 0; -out: -    return ret; -} - -/******************************************************************************* - * - *                      Fill wind into db record - * - ******************************************************************************/ -int -fill_db_record_for_wind(xlator_t *this, gf_ctr_local_t *ctr_local, -                        gf_ctr_inode_context_t *ctr_inode_cx) -{ -    int ret = -1; -    gfdb_time_t *ctr_wtime = NULL; -    gf_ctr_private_t *_priv = NULL; - -    GF_ASSERT(this); -    _priv = this->private; -    GF_ASSERT(_priv); -    GF_ASSERT(ctr_local); -    IS_CTR_INODE_CX_SANE(ctr_inode_cx); - -    /*if not wind path error!*/ -    if (!iswindpath(ctr_inode_cx->fop_path)) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_WRONG_FOP_PATH, -               "Wrong fop_path. Should be wind"); -        goto out; -    } - -    ctr_wtime = &CTR_DB_REC(ctr_local).gfdb_wind_change_time; -    CTR_DB_REC(ctr_local).gfdb_fop_path = ctr_inode_cx->fop_path; -    CTR_DB_REC(ctr_local).gfdb_fop_type = ctr_inode_cx->fop_type; -    CTR_DB_REC(ctr_local).link_consistency = _priv->ctr_link_consistency; - -    ret = gettimeofday(ctr_wtime, NULL); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, errno, -               CTR_MSG_FILL_UNWIND_TIME_REC_ERROR, -               "Error filling wind time record %s", strerror(errno)); -        goto out; -    } - -    /* Special case i.e if its a tier rebalance -     * + cold tier brick -     * + its a create/mknod FOP -     * we record wind time as zero */ -    if (ctr_local->client_pid == GF_CLIENT_PID_TIER_DEFRAG && -        (!_priv->ctr_hot_brick) && isdentrycreatefop(ctr_inode_cx->fop_type)) { -        memset(ctr_wtime, 0, sizeof(*ctr_wtime)); -    } - -    /* Copy gfid into db record */ -    gf_uuid_copy(CTR_DB_REC(ctr_local).gfid, *(ctr_inode_cx->gfid)); - -    /* Copy older gfid if any */ -    if (ctr_inode_cx->old_gfid && -        (!gf_uuid_is_null(*(ctr_inode_cx->old_gfid)))) { -        gf_uuid_copy(CTR_DB_REC(ctr_local).old_gfid, *(ctr_inode_cx->old_gfid)); -    } - -    /*Hard Links*/ -    if (isdentryfop(ctr_inode_cx->fop_type)) { -        /*new link fop*/ -        if (NEW_LINK_CX(ctr_inode_cx)) { -            gf_uuid_copy(CTR_DB_REC(ctr_local).pargfid, -                         *((NEW_LINK_CX(ctr_inode_cx))->pargfid)); -            strcpy(CTR_DB_REC(ctr_local).file_name, -                   NEW_LINK_CX(ctr_inode_cx)->basename); -        } -        /*rename fop*/ -        if (OLD_LINK_CX(ctr_inode_cx)) { -            gf_uuid_copy(CTR_DB_REC(ctr_local).old_pargfid, -                         *((OLD_LINK_CX(ctr_inode_cx))->pargfid)); -            strcpy(CTR_DB_REC(ctr_local).old_file_name, -                   OLD_LINK_CX(ctr_inode_cx)->basename); -        } -    } - -    ret = 0; -out: -    /*On error roll back and clean the record*/ -    if (ret == -1) { -        CLEAR_CTR_DB_RECORD(ctr_local); -    } -    return ret; -} - -/****************************************************************************** - * - *                      CTR xlator init related functions - * - * - * ****************************************************************************/ -static int -extract_sql_params(xlator_t *this, dict_t *params_dict) -{ -    int ret = -1; -    char *db_path = NULL; -    char *db_name = NULL; -    char *db_full_path = NULL; - -    GF_ASSERT(this); -    GF_ASSERT(params_dict); - -    /*Extract the path of the db*/ -    db_path = NULL; -    GET_DB_PARAM_FROM_DICT_DEFAULT(this->name, this->options, "db-path", -                                   db_path, "/var/run/gluster/"); - -    /*Extract the name of the db*/ -    db_name = NULL; -    GET_DB_PARAM_FROM_DICT_DEFAULT(this->name, this->options, "db-name", -                                   db_name, "gf_ctr_db.db"); - -    /*Construct full path of the db*/ -    ret = gf_asprintf(&db_full_path, "%s/%s", db_path, db_name); -    if (ret < 0) { -        gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, -               CTR_MSG_CONSTRUCT_DB_PATH_FAILED, -               "Construction of full db path failed!"); -        goto out; -    } - -    /*Setting the SQL DB Path*/ -    SET_DB_PARAM_TO_DICT(this->name, params_dict, GFDB_SQL_PARAM_DBPATH, -                         db_full_path, ret, out); - -    /*Extract rest of the sql params*/ -    ret = gfdb_set_sql_params(this->name, this->options, params_dict); -    if (ret) { -        gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, -               CTR_MSG_SET_VALUE_TO_SQL_PARAM_FAILED, -               "Failed setting values to sql param dict!"); -    } - -    ret = 0; - -out: -    if (ret) -        GF_FREE(db_full_path); -    return ret; -} - -int -extract_db_params(xlator_t *this, dict_t *params_dict, gfdb_db_type_t db_type) -{ -    int ret = -1; - -    GF_ASSERT(this); -    GF_ASSERT(params_dict); - -    switch (db_type) { -        case GFDB_SQLITE3: -            ret = extract_sql_params(this, params_dict); -            if (ret) -                goto out; -            break; -        case GFDB_ROCKS_DB: -        case GFDB_HYPERDEX: -        case GFDB_HASH_FILE_STORE: -        case GFDB_INVALID_DB: -        case GFDB_DB_END: -            goto out; -    } -    ret = 0; -out: -    return ret; -} - -int -extract_ctr_options(xlator_t *this, gf_ctr_private_t *_priv) -{ -    int ret = -1; -    char *_val_str = NULL; - -    GF_ASSERT(this); -    GF_ASSERT(_priv); - -    /*Checking if the CTR Translator is enabled. By default its disabled*/ -    _priv->enabled = _gf_false; -    GF_OPTION_INIT("ctr-enabled", _priv->enabled, bool, out); -    if (!_priv->enabled) { -        gf_msg(GFDB_DATA_STORE, GF_LOG_INFO, 0, CTR_MSG_XLATOR_DISABLED, -               "CTR Xlator is disabled."); -        ret = 0; -        goto out; -    } - -    /*Extract db type*/ -    GF_OPTION_INIT("db-type", _val_str, str, out); -    _priv->gfdb_db_type = gf_string2gfdbdbtype(_val_str); - -    /*Extract flag for record on wind*/ -    GF_OPTION_INIT("record-entry", _priv->ctr_record_wind, bool, out); - -    /*Extract flag for record on unwind*/ -    GF_OPTION_INIT("record-exit", _priv->ctr_record_unwind, bool, out); - -    /*Extract flag for record on counters*/ -    GF_OPTION_INIT("record-counters", _priv->ctr_record_counter, bool, out); - -    /* Extract flag for record metadata heat */ -    GF_OPTION_INIT("ctr-record-metadata-heat", _priv->ctr_record_metadata_heat, -                   bool, out); - -    /*Extract flag for link consistency*/ -    GF_OPTION_INIT("ctr_link_consistency", _priv->ctr_link_consistency, bool, -                   out); - -    /*Extract ctr_lookupheal_inode_timeout */ -    GF_OPTION_INIT("ctr_lookupheal_inode_timeout", -                   _priv->ctr_lookupheal_inode_timeout, uint64, out); - -    /*Extract ctr_lookupheal_link_timeout*/ -    GF_OPTION_INIT("ctr_lookupheal_link_timeout", -                   _priv->ctr_lookupheal_link_timeout, uint64, out); - -    /*Extract flag for hot tier brick*/ -    GF_OPTION_INIT("hot-brick", _priv->ctr_hot_brick, bool, out); - -    /*Extract flag for sync mode*/ -    GF_OPTION_INIT("db-sync", _val_str, str, out); -    _priv->gfdb_sync_type = gf_string2gfdbdbsync(_val_str); - -    ret = 0; - -out: -    return ret; -} diff --git a/xlators/features/changetimerecorder/src/ctr-helper.h b/xlators/features/changetimerecorder/src/ctr-helper.h deleted file mode 100644 index 517fbb0b7de..00000000000 --- a/xlators/features/changetimerecorder/src/ctr-helper.h +++ /dev/null @@ -1,854 +0,0 @@ -/* -   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#ifndef __CTR_HELPER_H -#define __CTR_HELPER_H - -#include <glusterfs/xlator.h> -#include "ctr_mem_types.h" -#include <glusterfs/iatt.h> -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/defaults.h> -#include <glusterfs/logging.h> -#include <glusterfs/common-utils.h> -#include <time.h> -#include <sys/time.h> -#include <pthread.h> - -#include "gfdb_data_store.h" -#include "ctr-xlator-ctx.h" -#include "ctr-messages.h" - -#define CTR_DEFAULT_HARDLINK_EXP_PERIOD 300 /* Five mins */ -#define CTR_DEFAULT_INODE_EXP_PERIOD 300    /* Five mins */ - -typedef struct ctr_query_cbk_args { -    int query_fd; -    int count; -} ctr_query_cbk_args_t; - -/*CTR Xlator Private structure*/ -typedef struct gf_ctr_private { -    gf_boolean_t enabled; -    char *ctr_db_path; -    gf_boolean_t ctr_hot_brick; -    gf_boolean_t ctr_record_wind; -    gf_boolean_t ctr_record_unwind; -    gf_boolean_t ctr_record_counter; -    gf_boolean_t ctr_record_metadata_heat; -    gf_boolean_t ctr_link_consistency; -    gfdb_db_type_t gfdb_db_type; -    gfdb_sync_type_t gfdb_sync_type; -    gfdb_conn_node_t *_db_conn; -    uint64_t ctr_lookupheal_link_timeout; -    uint64_t ctr_lookupheal_inode_timeout; -    gf_boolean_t compact_active; -    gf_boolean_t compact_mode_switched; -    pthread_mutex_t compact_lock; -} gf_ctr_private_t; - -/* - * gf_ctr_local_t is the ctr xlator local data structure that is stored in - * the call_frame of each FOP. - * - * gfdb_db_record: The gf_ctr_local contains a gfdb_db_record object, which is - * used by the insert_record() api from the libgfdb. The gfdb_db_record object - * will contain all the inode and hardlink(only for dentry fops: create, - * mknod,link, unlink, rename).The ctr_local is keep alive till the unwind - * call and will be release during the unwind. The same gfdb_db_record will - * used for the unwind insert_record() api, to record unwind in the database. - * - * ia_inode_type in gf_ctr_local will tell the type of the inode. This is - * important for during the unwind path. As we will not have the inode during - * the unwind path. We would have include this in the gfdb_db_record itself - * but currently we record only file inode information. - * - * is_internal_fop in gf_ctr_local will tell us if this is a internal fop and - * take special/no action. We don't record change/access times or increement - * heat counter for internal fops from rebalancer. - * */ -typedef struct gf_ctr_local { -    gfdb_db_record_t gfdb_db_record; -    ia_type_t ia_inode_type; -    gf_boolean_t is_internal_fop; -    gf_special_pid_t client_pid; -} gf_ctr_local_t; -/* - * Easy access of gfdb_db_record of ctr_local - * */ -#define CTR_DB_REC(ctr_local) (ctr_local->gfdb_db_record) - -/*Clear db record*/ -#define CLEAR_CTR_DB_RECORD(ctr_local)                                         \ -    do {                                                                       \ -        ctr_local->gfdb_db_record.gfdb_fop_path = GFDB_FOP_INVALID;            \ -        memset(&(ctr_local->gfdb_db_record.gfdb_wind_change_time), 0,          \ -               sizeof(gfdb_time_t));                                           \ -        memset(&(ctr_local->gfdb_db_record.gfdb_unwind_change_time), 0,        \ -               sizeof(gfdb_time_t));                                           \ -        gf_uuid_clear(ctr_local->gfdb_db_record.gfid);                         \ -        gf_uuid_clear(ctr_local->gfdb_db_record.pargfid);                      \ -        memset(ctr_local->gfdb_db_record.file_name, 0, GF_NAME_MAX + 1);       \ -        memset(ctr_local->gfdb_db_record.old_file_name, 0, GF_NAME_MAX + 1);   \ -        ctr_local->gfdb_db_record.gfdb_fop_type = GFDB_FOP_INVALID_OP;         \ -        ctr_local->ia_inode_type = IA_INVAL;                                   \ -    } while (0) - -static gf_ctr_local_t * -init_ctr_local_t(xlator_t *this) -{ -    gf_ctr_local_t *ctr_local = NULL; - -    GF_ASSERT(this); - -    ctr_local = mem_get0(this->local_pool); -    if (!ctr_local) { -        gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, -               CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND, -               "Error while creating ctr local"); -        goto out; -    } - -    CLEAR_CTR_DB_RECORD(ctr_local); -out: -    return ctr_local; -} - -static void -free_ctr_local(gf_ctr_local_t *ctr_local) -{ -    if (ctr_local) -        mem_put(ctr_local); -} - -/****************************************************************************** - * - * - *                      Context Carrier Structures - * - * - * ****************************************************************************/ - -/* - * Context Carrier structures are used to carry relevant information about - * inodes and links from the fops calls to the ctr_insert_wind. - * These structure just have pointers to the original data and donot - * do a deep copy of any data. This info is deep copied to - * ctr_local->gfdb_db_record and passed to insert_record() api of libgfdb. This - * info remains persistent for the unwind in  ctr_local->gfdb_db_record - * and once used will be destroyed. - * - * gf_ctr_link_context_t : Context structure for hard links - * gf_ctr_inode_context_t : Context structure for inodes - * - * */ - -/*Context Carrier Structure for hard links*/ -typedef struct gf_ctr_link_context { -    uuid_t *pargfid; -    const char *basename; -} gf_ctr_link_context_t; - -/*Context Carrier Structure for inodes*/ -typedef struct gf_ctr_inode_context { -    ia_type_t ia_type; -    uuid_t *gfid; -    uuid_t *old_gfid; -    gf_ctr_link_context_t *new_link_cx; -    gf_ctr_link_context_t *old_link_cx; -    gfdb_fop_type_t fop_type; -    gfdb_fop_path_t fop_path; -    gf_boolean_t is_internal_fop; -    /* Indicating metadata fops */ -    gf_boolean_t is_metadata_fop; -} gf_ctr_inode_context_t; - -/*******************Util Macros for Context Carrier Structures*****************/ - -/*Checks if ctr_link_cx is sane!*/ -#define IS_CTR_LINK_CX_SANE(ctr_link_cx)                                       \ -    do {                                                                       \ -        if (ctr_link_cx) {                                                     \ -            if (ctr_link_cx->pargfid)                                          \ -                GF_ASSERT(*(ctr_link_cx->pargfid));                            \ -            GF_ASSERT(ctr_link_cx->basename);                                  \ -        };                                                                     \ -    } while (0) - -/*Clear and fill the ctr_link_context with values*/ -#define FILL_CTR_LINK_CX(ctr_link_cx, _pargfid, _basename, label)              \ -    do {                                                                       \ -        GF_VALIDATE_OR_GOTO("ctr", ctr_link_cx, label);                        \ -        GF_VALIDATE_OR_GOTO("ctr", _pargfid, label);                           \ -        GF_VALIDATE_OR_GOTO("ctr", _basename, label);                          \ -        memset(ctr_link_cx, 0, sizeof(*ctr_link_cx));                          \ -        ctr_link_cx->pargfid = &_pargfid;                                      \ -        ctr_link_cx->basename = _basename;                                     \ -    } while (0) - -#define NEW_LINK_CX(ctr_inode_cx) ctr_inode_cx->new_link_cx - -#define OLD_LINK_CX(ctr_inode_cx) ctr_inode_cx->old_link_cx - -/*Checks if ctr_inode_cx is sane!*/ -#define IS_CTR_INODE_CX_SANE(ctr_inode_cx)                                     \ -    do {                                                                       \ -        GF_ASSERT(ctr_inode_cx);                                               \ -        GF_ASSERT(ctr_inode_cx->gfid);                                         \ -        GF_ASSERT(*(ctr_inode_cx->gfid));                                      \ -        GF_ASSERT(ctr_inode_cx->fop_type != GFDB_FOP_INVALID_OP);              \ -        GF_ASSERT(ctr_inode_cx->fop_path != GFDB_FOP_INVALID);                 \ -        IS_CTR_LINK_CX_SANE(NEW_LINK_CX(ctr_inode_cx));                        \ -        IS_CTR_LINK_CX_SANE(OLD_LINK_CX(ctr_inode_cx));                        \ -    } while (0) - -/*Clear and fill the ctr_inode_context with values*/ -#define FILL_CTR_INODE_CONTEXT(ctr_inode_cx, _ia_type, _gfid, _new_link_cx,    \ -                               _old_link_cx, _fop_type, _fop_path)             \ -    do {                                                                       \ -        GF_ASSERT(ctr_inode_cx);                                               \ -        GF_ASSERT(_gfid);                                                      \ -        GF_ASSERT(_fop_type != GFDB_FOP_INVALID_OP);                           \ -        GF_ASSERT(_fop_path != GFDB_FOP_INVALID);                              \ -        memset(ctr_inode_cx, 0, sizeof(*ctr_inode_cx));                        \ -        ctr_inode_cx->ia_type = _ia_type;                                      \ -        ctr_inode_cx->gfid = &_gfid;                                           \ -        IS_CTR_LINK_CX_SANE(NEW_LINK_CX(ctr_inode_cx));                        \ -        if (_new_link_cx)                                                      \ -            NEW_LINK_CX(ctr_inode_cx) = _new_link_cx;                          \ -        IS_CTR_LINK_CX_SANE(OLD_LINK_CX(ctr_inode_cx));                        \ -        if (_old_link_cx)                                                      \ -            OLD_LINK_CX(ctr_inode_cx) = _old_link_cx;                          \ -        ctr_inode_cx->fop_type = _fop_type;                                    \ -        ctr_inode_cx->fop_path = _fop_path;                                    \ -    } while (0) - -/****************************************************************************** - * - *                      Util functions or macros used by - *                      insert wind and insert unwind - * - * ****************************************************************************/ -/* Free ctr frame local */ -static inline void -ctr_free_frame_local(call_frame_t *frame) -{ -    if (frame) { -        free_ctr_local((gf_ctr_local_t *)frame->local); -        frame->local = NULL; -    } -} - -/* Setting GF_REQUEST_LINK_COUNT_XDATA in dict - * that has to be sent to POSIX Xlator to send - * link count in unwind path. - * return 0 for success with not creation of dict - * return 1 for success with creation of dict - * return -1 for failure. - * */ -static inline int -set_posix_link_request(xlator_t *this, dict_t **xdata) -{ -    int ret = -1; -    gf_boolean_t is_created = _gf_false; - -    GF_VALIDATE_OR_GOTO("ctr", this, out); -    GF_VALIDATE_OR_GOTO(this->name, xdata, out); - -    /*create xdata if NULL*/ -    if (!*xdata) { -        *xdata = dict_new(); -        is_created = _gf_true; -        ret = 1; -    } else { -        ret = 0; -    } - -    if (!*xdata) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_XDATA_NULL, -               "xdata is NULL :Cannot send " -               "GF_REQUEST_LINK_COUNT_XDATA to posix"); -        ret = -1; -        goto out; -    } - -    ret = dict_set_int32(*xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_SET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, -               "Failed setting GF_REQUEST_LINK_COUNT_XDATA"); -        ret = -1; -        goto out; -    } -    ret = 0; -out: -    if (ret == -1) { -        if (*xdata && is_created) { -            dict_unref(*xdata); -        } -    } -    return ret; -} - -/* - * If a bitrot fop - * */ -#define BITROT_FOP(frame)                                                      \ -    (frame->root->pid == GF_CLIENT_PID_BITD ||                                 \ -     frame->root->pid == GF_CLIENT_PID_SCRUB) - -/* - * If a rebalancer fop - * */ -#define REBALANCE_FOP(frame) (frame->root->pid == GF_CLIENT_PID_DEFRAG) - -/* - * If its a tiering rebalancer fop - * */ -#define TIER_REBALANCE_FOP(frame)                                              \ -    (frame->root->pid == GF_CLIENT_PID_TIER_DEFRAG) - -/* - * If its a AFR SELF HEAL - * */ -#define AFR_SELF_HEAL_FOP(frame) (frame->root->pid == GF_CLIENT_PID_SELF_HEALD) - -/* - * if a rebalancer fop goto - * */ -#define CTR_IF_REBALANCE_FOP_THEN_GOTO(frame, label)                           \ -    do {                                                                       \ -        if (REBALANCE_FOP(frame))                                              \ -            goto label;                                                        \ -    } while (0) - -/* - * Internal fop - * - * */ -static inline gf_boolean_t -is_internal_fop(call_frame_t *frame, dict_t *xdata) -{ -    gf_boolean_t ret = _gf_false; - -    GF_ASSERT(frame); -    GF_ASSERT(frame->root); - -    if (AFR_SELF_HEAL_FOP(frame)) { -        ret = _gf_true; -    } -    if (BITROT_FOP(frame)) { -        ret = _gf_true; -    } -    if (REBALANCE_FOP(frame) || TIER_REBALANCE_FOP(frame)) { -        ret = _gf_true; -        if (xdata && dict_get(xdata, CTR_ATTACH_TIER_LOOKUP)) { -            ret = _gf_false; -        } -    } -    if (xdata && dict_get(xdata, GLUSTERFS_INTERNAL_FOP_KEY)) { -        ret = _gf_true; -    } - -    return ret; -} - -#define CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, dict, label)                      \ -    do {                                                                       \ -        if (is_internal_fop(frame, dict))                                      \ -            goto label;                                                        \ -    } while (0) - -/* if fop has failed exit */ -#define CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, label)             \ -    do {                                                                       \ -        if (op_ret == -1) {                                                    \ -            gf_msg_trace(this->name, 0, "Failed fop with %s",                  \ -                         strerror(op_errno));                                  \ -            goto label;                                                        \ -        };                                                                     \ -    } while (0) - -/* - * IS CTR Xlator is disabled then goto to label - * */ -#define CTR_IS_DISABLED_THEN_GOTO(this, label)                                 \ -    do {                                                                       \ -        gf_ctr_private_t *_priv = NULL;                                        \ -        GF_ASSERT(this);                                                       \ -        GF_ASSERT(this->private);                                              \ -        _priv = this->private;                                                 \ -        if (!_priv->_db_conn)                                                  \ -            goto label;                                                        \ -    } while (0) - -/* - * IS CTR record metadata heat is disabled then goto to label - * */ -#define CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, label)            \ -    do {                                                                       \ -        gf_ctr_private_t *_priv = NULL;                                        \ -        GF_ASSERT(this);                                                       \ -        GF_ASSERT(this->private);                                              \ -        _priv = this->private;                                                 \ -        if (!_priv->ctr_record_metadata_heat)                                  \ -            goto label;                                                        \ -    } while (0) - -int -fill_db_record_for_unwind(xlator_t *this, gf_ctr_local_t *ctr_local, -                          gfdb_fop_type_t fop_type, gfdb_fop_path_t fop_path); - -int -fill_db_record_for_wind(xlator_t *this, gf_ctr_local_t *ctr_local, -                        gf_ctr_inode_context_t *ctr_inode_cx); - -/******************************************************************************* - *                              CTR INSERT WIND - * ***************************************************************************** - * Function used to insert/update record into the database during a wind fop - * This function creates ctr_local structure into the frame of the fop - * call. - * ****************************************************************************/ - -static inline int -ctr_insert_wind(call_frame_t *frame, xlator_t *this, -                gf_ctr_inode_context_t *ctr_inode_cx) -{ -    int ret = -1; -    gf_ctr_private_t *_priv = NULL; -    gf_ctr_local_t *ctr_local = NULL; - -    GF_ASSERT(frame); -    GF_ASSERT(frame->root); -    GF_ASSERT(this); -    IS_CTR_INODE_CX_SANE(ctr_inode_cx); - -    _priv = this->private; -    GF_ASSERT(_priv); - -    GF_ASSERT(_priv->_db_conn); - -    /*If record_wind option of CTR is on record wind for -     * regular files only*/ -    if (_priv->ctr_record_wind && ctr_inode_cx->ia_type != IA_IFDIR) { -        frame->local = init_ctr_local_t(this); -        if (!frame->local) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND, -                   "WIND: Error while creating ctr local"); -            goto out; -        }; -        ctr_local = frame->local; -        ctr_local->client_pid = frame->root->pid; -        ctr_local->is_internal_fop = ctr_inode_cx->is_internal_fop; - -        /* Decide whether to record counters or not */ -        CTR_DB_REC(ctr_local).do_record_counters = _gf_false; -        /* If record counter is enabled */ -        if (_priv->ctr_record_counter) { -            /* If not a internal fop */ -            if (!(ctr_local->is_internal_fop)) { -                /* If its a metadata fop AND -                 * record metadata heat -                 * OR -                 * its NOT a metadata fop */ -                if ((ctr_inode_cx->is_metadata_fop && -                     _priv->ctr_record_metadata_heat) || -                    (!ctr_inode_cx->is_metadata_fop)) { -                    CTR_DB_REC(ctr_local).do_record_counters = _gf_true; -                } -            } -        } - -        /* Decide whether to record times or not -         * For non internal FOPS record times as usual*/ -        CTR_DB_REC(ctr_local).do_record_times = _gf_false; -        if (!ctr_local->is_internal_fop) { -            /* If its a metadata fop AND -             * record metadata heat -             * OR -             * its NOT a metadata fop */ -            if ((ctr_inode_cx->is_metadata_fop && -                 _priv->ctr_record_metadata_heat) || -                (!ctr_inode_cx->is_metadata_fop)) { -                CTR_DB_REC(ctr_local).do_record_times = -                    (_priv->ctr_record_wind || _priv->ctr_record_unwind); -            } -        } -        /* when its a internal FOPS*/ -        else { -            /* Record times only for create -             * i.e when the inode is created */ -            CTR_DB_REC(ctr_local).do_record_times = (isdentrycreatefop( -                                                        ctr_inode_cx->fop_type)) -                                                        ? _gf_true -                                                        : _gf_false; -        } - -        /*Fill the db record for insertion*/ -        ret = fill_db_record_for_wind(this, ctr_local, ctr_inode_cx); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_FILL_CTR_LOCAL_ERROR_WIND, -                   "WIND: Error filling  ctr local"); -            goto out; -        } - -        /*Insert the db record*/ -        ret = insert_record(_priv->_db_conn, &ctr_local->gfdb_db_record); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_INSERT_RECORD_WIND_FAILED, -                   "WIND: Inserting of record failed!"); -            goto out; -        } -    } -    ret = 0; -out: - -    if (ret) { -        free_ctr_local(ctr_local); -        frame->local = NULL; -    } - -    return ret; -} - -/******************************************************************************* - *                             CTR INSERT UNWIND - * ***************************************************************************** - * Function used to insert/update record into the database during a unwind fop - * This function destroys ctr_local structure into the frame of the fop - * call at the end. - * ****************************************************************************/ -static inline int -ctr_insert_unwind(call_frame_t *frame, xlator_t *this, gfdb_fop_type_t fop_type, -                  gfdb_fop_path_t fop_path) -{ -    int ret = -1; -    gf_ctr_private_t *_priv = NULL; -    gf_ctr_local_t *ctr_local = NULL; - -    GF_ASSERT(frame); -    GF_ASSERT(this); - -    _priv = this->private; -    GF_ASSERT(_priv); - -    GF_ASSERT(_priv->_db_conn); - -    ctr_local = frame->local; - -    if (ctr_local && (_priv->ctr_record_unwind || isdentryfop(fop_type)) && -        (ctr_local->ia_inode_type != IA_IFDIR)) { -        CTR_DB_REC(ctr_local).do_record_uwind_time = _priv->ctr_record_unwind; - -        ret = fill_db_record_for_unwind(this, ctr_local, fop_type, fop_path); -        if (ret == -1) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND, -                   "UNWIND: Error filling ctr local"); -            goto out; -        } - -        ret = insert_record(_priv->_db_conn, &ctr_local->gfdb_db_record); -        if (ret == -1) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND, -                   "UNWIND: Error filling ctr local"); -            goto out; -        } -    } -    ret = 0; -out: -    return ret; -} - -/****************************************************************************** - *                          Delete file/flink record/s from db - * ****************************************************************************/ -static inline int -ctr_delete_hard_link_from_db(xlator_t *this, uuid_t gfid, uuid_t pargfid, -                             char *basename, gfdb_fop_type_t fop_type, -                             gfdb_fop_path_t fop_path) -{ -    int ret = -1; -    gfdb_db_record_t gfdb_db_record; -    gf_ctr_private_t *_priv = NULL; - -    _priv = this->private; -    GF_VALIDATE_OR_GOTO(this->name, _priv, out); -    GF_VALIDATE_OR_GOTO(this->name, (!gf_uuid_is_null(gfid)), out); -    GF_VALIDATE_OR_GOTO(this->name, (!gf_uuid_is_null(pargfid)), out); -    GF_VALIDATE_OR_GOTO(this->name, (fop_type == GFDB_FOP_DENTRY_WRITE), out); -    GF_VALIDATE_OR_GOTO( -        this->name, (fop_path == GFDB_FOP_UNDEL || GFDB_FOP_UNDEL_ALL), out); - -    /* Set gfdb_db_record to 0 */ -    memset(&gfdb_db_record, 0, sizeof(gfdb_db_record)); - -    /* Copy basename */ -    if (snprintf(gfdb_db_record.file_name, GF_NAME_MAX, "%s", basename) >= -        GF_NAME_MAX) -        goto out; - -    /* Copy gfid into db record */ -    gf_uuid_copy(gfdb_db_record.gfid, gfid); - -    /* Copy pargid into db record */ -    gf_uuid_copy(gfdb_db_record.pargfid, pargfid); - -    gfdb_db_record.gfdb_fop_path = fop_path; -    gfdb_db_record.gfdb_fop_type = fop_type; - -    /*send delete request to db*/ -    ret = insert_record(_priv->_db_conn, &gfdb_db_record); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_RECORD_WIND_FAILED, -               "Failed to delete record. %s", basename); -        goto out; -    } - -    ret = 0; -out: -    return ret; -} - -/******************************* Hard link function ***************************/ - -static inline gf_boolean_t -__is_inode_expired(ctr_xlator_ctx_t *ctr_xlator_ctx, gf_ctr_private_t *_priv, -                   gfdb_time_t *current_time) -{ -    gf_boolean_t ret = _gf_false; -    uint64_t time_diff = 0; - -    GF_ASSERT(ctr_xlator_ctx); -    GF_ASSERT(_priv); -    GF_ASSERT(current_time); - -    time_diff = current_time->tv_sec - ctr_xlator_ctx->inode_heal_period; - -    ret = (time_diff >= _priv->ctr_lookupheal_inode_timeout) ? _gf_true -                                                             : _gf_false; -    return ret; -} - -static inline gf_boolean_t -__is_hardlink_expired(ctr_hard_link_t *ctr_hard_link, gf_ctr_private_t *_priv, -                      gfdb_time_t *current_time) -{ -    gf_boolean_t ret = _gf_false; -    uint64_t time_diff = 0; - -    GF_ASSERT(ctr_hard_link); -    GF_ASSERT(_priv); -    GF_ASSERT(current_time); - -    time_diff = current_time->tv_sec - ctr_hard_link->hardlink_heal_period; - -    ret = ret || (time_diff >= _priv->ctr_lookupheal_link_timeout) ? _gf_true -                                                                   : _gf_false; - -    return ret; -} - -/* Return values of heal*/ -typedef enum ctr_heal_ret_val { -    CTR_CTX_ERROR = -1, -    /* No healing required */ -    CTR_TRY_NO_HEAL = 0, -    /* Try healing hard link */ -    CTR_TRY_HARDLINK_HEAL = 1, -    /* Try healing inode */ -    CTR_TRY_INODE_HEAL = 2, -} ctr_heal_ret_val_t; - -/** - * @brief Function to add hard link to the inode context variable. - *        The inode context maintainences a in-memory list. This is used - *        smart healing of database. - * @param frame of the FOP - * @param this is the Xlator instant - * @param inode - * @return Return ctr_heal_ret_val_t - */ - -static inline ctr_heal_ret_val_t -add_hard_link_ctx(call_frame_t *frame, xlator_t *this, inode_t *inode) -{ -    ctr_heal_ret_val_t ret_val = CTR_TRY_NO_HEAL; -    int ret = -1; -    gf_ctr_local_t *ctr_local = NULL; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; -    ctr_hard_link_t *ctr_hard_link = NULL; -    gf_ctr_private_t *_priv = NULL; -    gfdb_time_t current_time = {0}; - -    GF_ASSERT(frame); -    GF_ASSERT(this); -    GF_ASSERT(inode); -    GF_ASSERT(this->private); - -    _priv = this->private; - -    ctr_local = frame->local; -    if (!ctr_local) { -        goto out; -    } - -    ctr_xlator_ctx = init_ctr_xlator_ctx(this, inode); -    if (!ctr_xlator_ctx) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_ACCESS_CTR_INODE_CONTEXT_FAILED, -               "Failed accessing ctr inode context"); -        goto out; -    } - -    LOCK(&ctr_xlator_ctx->lock); - -    /* Check if the hard link already exists -     * in the ctr inode context*/ -    ctr_hard_link = ctr_search_hard_link_ctx(this, ctr_xlator_ctx, -                                             CTR_DB_REC(ctr_local).pargfid, -                                             CTR_DB_REC(ctr_local).file_name); -    /* if there then ignore */ -    if (ctr_hard_link) { -        ret = gettimeofday(¤t_time, NULL); -        if (ret == -1) { -            gf_log(this->name, GF_LOG_ERROR, "Failed to get current time"); -            ret_val = CTR_CTX_ERROR; -            goto unlock; -        } - -        if (__is_hardlink_expired(ctr_hard_link, _priv, ¤t_time)) { -            ctr_hard_link->hardlink_heal_period = current_time.tv_sec; -            ret_val = ret_val | CTR_TRY_HARDLINK_HEAL; -        } - -        if (__is_inode_expired(ctr_xlator_ctx, _priv, ¤t_time)) { -            ctr_xlator_ctx->inode_heal_period = current_time.tv_sec; -            ret_val = ret_val | CTR_TRY_INODE_HEAL; -        } - -        goto unlock; -    } - -    /* Add the hard link to the list*/ -    ret = ctr_add_hard_link(this, ctr_xlator_ctx, CTR_DB_REC(ctr_local).pargfid, -                            CTR_DB_REC(ctr_local).file_name); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_ADD_HARDLINK_TO_CTR_INODE_CONTEXT_FAILED, -               "Failed to add hardlink to the ctr inode context"); -        ret_val = CTR_CTX_ERROR; -        goto unlock; -    } - -    ret_val = CTR_TRY_NO_HEAL; -unlock: -    UNLOCK(&ctr_xlator_ctx->lock); -out: -    return ret_val; -} - -static inline int -delete_hard_link_ctx(call_frame_t *frame, xlator_t *this, inode_t *inode) -{ -    int ret = -1; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; -    gf_ctr_local_t *ctr_local = NULL; - -    GF_ASSERT(frame); -    GF_ASSERT(this); -    GF_ASSERT(inode); - -    ctr_local = frame->local; -    if (!ctr_local) { -        goto out; -    } - -    ctr_xlator_ctx = get_ctr_xlator_ctx(this, inode); -    if (!ctr_xlator_ctx) { -        /* Since there is no ctr inode context so nothing more to do */ -        ret = 0; -        goto out; -    } - -    ret = ctr_delete_hard_link(this, ctr_xlator_ctx, -                               CTR_DB_REC(ctr_local).pargfid, -                               CTR_DB_REC(ctr_local).file_name); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_DELETE_HARDLINK_FAILED, -               "Failed to delete hard link"); -        goto out; -    } - -    ret = 0; - -out: -    return ret; -} - -static inline int -update_hard_link_ctx(call_frame_t *frame, xlator_t *this, inode_t *inode) -{ -    int ret = -1; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; -    gf_ctr_local_t *ctr_local = NULL; - -    GF_ASSERT(frame); -    GF_ASSERT(this); -    GF_ASSERT(inode); - -    ctr_local = frame->local; -    if (!ctr_local) { -        goto out; -    } - -    ctr_xlator_ctx = init_ctr_xlator_ctx(this, inode); -    if (!ctr_xlator_ctx) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               CTR_MSG_ACCESS_CTR_INODE_CONTEXT_FAILED, -               "Failed accessing ctr inode context"); -        goto out; -    } - -    ret = ctr_update_hard_link( -        this, ctr_xlator_ctx, CTR_DB_REC(ctr_local).pargfid, -        CTR_DB_REC(ctr_local).file_name, CTR_DB_REC(ctr_local).old_pargfid, -        CTR_DB_REC(ctr_local).old_file_name); -    if (ret) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_DELETE_HARDLINK_FAILED, -               "Failed to delete hard link"); -        goto out; -    } - -    ret = 0; - -out: -    return ret; -} - -/****************************************************************************** - * - *                      CTR xlator init related functions - * - * - * ****************************************************************************/ -int -extract_db_params(xlator_t *this, dict_t *params_dict, gfdb_db_type_t db_type); - -int -extract_ctr_options(xlator_t *this, gf_ctr_private_t *_priv); - -#endif diff --git a/xlators/features/changetimerecorder/src/ctr-messages.h b/xlators/features/changetimerecorder/src/ctr-messages.h deleted file mode 100644 index 23adf0aec09..00000000000 --- a/xlators/features/changetimerecorder/src/ctr-messages.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com> - This file is part of GlusterFS. - - This file is licensed to you under your choice of the GNU Lesser - General Public License, version 3 or any later version (LGPLv3 or - later), or the GNU General Public License, version 2 (GPLv2), in all - cases as published by the Free Software Foundation. - */ - -#ifndef _CTR_MESSAGES_H_ -#define _CTR_MESSAGES_H_ - -#include <glusterfs/glfs-message-id.h> - -/* To add new message IDs, append new identifiers at the end of the list. - * - * Never remove a message ID. If it's not used anymore, you can rename it or - * leave it as it is, but not delete it. This is to prevent reutilization of - * IDs by other messages. - * - * The component name must match one of the entries defined in - * glfs-message-id.h. - */ - -GLFS_MSGID( -    CTR, CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND, -    CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND, CTR_MSG_FILL_CTR_LOCAL_ERROR_WIND, -    CTR_MSG_INSERT_LINK_WIND_FAILED, CTR_MSG_INSERT_WRITEV_WIND_FAILED, -    CTR_MSG_INSERT_WRITEV_UNWIND_FAILED, CTR_MSG_INSERT_SETATTR_WIND_FAILED, -    CTR_MSG_INSERT_SETATTR_UNWIND_FAILED, -    CTR_MSG_INSERT_FREMOVEXATTR_UNWIND_FAILED, -    CTR_MSG_INSERT_FREMOVEXATTR_WIND_FAILED, -    CTR_MSG_INSERT_REMOVEXATTR_WIND_FAILED, -    CTR_MSG_INSERT_REMOVEXATTR_UNWIND_FAILED, -    CTR_MSG_INSERT_TRUNCATE_WIND_FAILED, CTR_MSG_INSERT_TRUNCATE_UNWIND_FAILED, -    CTR_MSG_INSERT_FTRUNCATE_UNWIND_FAILED, -    CTR_MSG_INSERT_FTRUNCATE_WIND_FAILED, CTR_MSG_INSERT_RENAME_WIND_FAILED, -    CTR_MSG_INSERT_RENAME_UNWIND_FAILED, -    CTR_MSG_ACCESS_CTR_INODE_CONTEXT_FAILED, CTR_MSG_ADD_HARDLINK_FAILED, -    CTR_MSG_DELETE_HARDLINK_FAILED, CTR_MSG_UPDATE_HARDLINK_FAILED, -    CTR_MSG_GET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, -    CTR_MSG_SET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED, -    CTR_MSG_INSERT_UNLINK_UNWIND_FAILED, CTR_MSG_INSERT_UNLINK_WIND_FAILED, -    CTR_MSG_XDATA_NULL, CTR_MSG_INSERT_FSYNC_WIND_FAILED, -    CTR_MSG_INSERT_FSYNC_UNWIND_FAILED, CTR_MSG_INSERT_MKNOD_UNWIND_FAILED, -    CTR_MSG_INSERT_MKNOD_WIND_FAILED, CTR_MSG_INSERT_CREATE_WIND_FAILED, -    CTR_MSG_INSERT_CREATE_UNWIND_FAILED, CTR_MSG_INSERT_RECORD_WIND_FAILED, -    CTR_MSG_INSERT_READV_WIND_FAILED, CTR_MSG_GET_GFID_FROM_DICT_FAILED, -    CTR_MSG_SET, CTR_MSG_FATAL_ERROR, CTR_MSG_DANGLING_VOLUME, -    CTR_MSG_CALLOC_FAILED, CTR_MSG_EXTRACT_CTR_XLATOR_OPTIONS_FAILED, -    CTR_MSG_INIT_DB_PARAMS_FAILED, CTR_MSG_CREATE_LOCAL_MEMORY_POOL_FAILED, -    CTR_MSG_MEM_ACC_INIT_FAILED, CTR_MSG_CLOSE_DB_CONN_FAILED, -    CTR_MSG_FILL_UNWIND_TIME_REC_ERROR, CTR_MSG_WRONG_FOP_PATH, -    CTR_MSG_CONSTRUCT_DB_PATH_FAILED, CTR_MSG_SET_VALUE_TO_SQL_PARAM_FAILED, -    CTR_MSG_XLATOR_DISABLED, CTR_MSG_HARDLINK_MISSING_IN_LIST, -    CTR_MSG_ADD_HARDLINK_TO_LIST_FAILED, CTR_MSG_INIT_LOCK_FAILED, -    CTR_MSG_COPY_FAILED, CTR_MSG_EXTRACT_DB_PARAM_OPTIONS_FAILED, -    CTR_MSG_ADD_HARDLINK_TO_CTR_INODE_CONTEXT_FAILED, CTR_MSG_NULL_LOCAL); - -#endif /* !_CTR_MESSAGES_H_ */ diff --git a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c deleted file mode 100644 index b6b66d56731..00000000000 --- a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c +++ /dev/null @@ -1,362 +0,0 @@ -/* -   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#include "ctr-xlator-ctx.h" -#include "ctr-messages.h" -#include <time.h> -#include <sys/time.h> - -#define IS_THE_ONLY_HARDLINK(ctr_hard_link)                                    \ -    (ctr_hard_link->list.next == ctr_hard_link->list.prev) - -static void -fini_ctr_hard_link(ctr_hard_link_t **ctr_hard_link) -{ -    GF_ASSERT(ctr_hard_link); - -    if (*ctr_hard_link) -        return; -    GF_FREE((*ctr_hard_link)->base_name); -    GF_FREE(*ctr_hard_link); -    *ctr_hard_link = NULL; -} - -/* Please lock the ctr_xlator_ctx before using this function */ -ctr_hard_link_t * -ctr_search_hard_link_ctx(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                         uuid_t pgfid, const char *base_name) -{ -    ctr_hard_link_t *_hard_link = NULL; -    ctr_hard_link_t *searched_hardlink = NULL; - -    GF_ASSERT(this); -    GF_ASSERT(ctr_xlator_ctx); - -    if (pgfid == NULL || base_name == NULL) -        goto out; - -    /*linear search*/ -    list_for_each_entry(_hard_link, &ctr_xlator_ctx->hardlink_list, list) -    { -        if (gf_uuid_compare(_hard_link->pgfid, pgfid) == 0 && -            _hard_link->base_name && -            strcmp(_hard_link->base_name, base_name) == 0) { -            searched_hardlink = _hard_link; -            break; -        } -    } - -out: -    return searched_hardlink; -} - -/* Please lock the ctr_xlator_ctx before using this function */ -int -ctr_add_hard_link(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                  uuid_t pgfid, const char *base_name) -{ -    int ret = -1; -    ctr_hard_link_t *ctr_hard_link = NULL; -    struct timeval current_time = {0}; - -    GF_ASSERT(this); -    GF_ASSERT(ctr_xlator_ctx); - -    if (pgfid == NULL || base_name == NULL) -        goto out; - -    ctr_hard_link = GF_CALLOC(1, sizeof(*ctr_hard_link), gf_ctr_mt_hard_link_t); -    if (!ctr_hard_link) { -        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, CTR_MSG_CALLOC_FAILED, -               "Failed allocating " -               "ctr_hard_link"); -        goto out; -    } - -    /*Initialize the ctr_hard_link object and -     * Assign the values : parent GFID and basename*/ -    INIT_LIST_HEAD(&ctr_hard_link->list); -    gf_uuid_copy(ctr_hard_link->pgfid, pgfid); -    ret = gf_asprintf(&ctr_hard_link->base_name, "%s", base_name); -    if (ret < 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_COPY_FAILED, -               "Failed copying basename" -               "to ctr_hard_link"); -        goto error; -    } - -    ret = gettimeofday(¤t_time, NULL); -    if (ret == -1) { -        gf_log(this->name, GF_LOG_ERROR, "Failed to get current time"); -        goto error; -    } - -    /*Add the hard link to the list*/ -    list_add_tail(&ctr_hard_link->list, &ctr_xlator_ctx->hardlink_list); - -    ctr_hard_link->hardlink_heal_period = current_time.tv_sec; - -    /*aal izz well!*/ -    ret = 0; -    goto out; -error: -    GF_FREE(ctr_hard_link); -out: -    return ret; -} - -static void -__delete_hard_link_from_list(ctr_hard_link_t **ctr_hard_link) -{ -    GF_ASSERT(ctr_hard_link); -    GF_ASSERT(*ctr_hard_link); - -    /*Remove hard link from list*/ -    list_del(&(*ctr_hard_link)->list); -    fini_ctr_hard_link(ctr_hard_link); -} - -int -ctr_delete_hard_link(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                     uuid_t pgfid, const char *base_name) -{ -    int ret = -1; -    ctr_hard_link_t *ctr_hard_link = NULL; - -    GF_ASSERT(this); -    GF_ASSERT(ctr_xlator_ctx); - -    LOCK(&ctr_xlator_ctx->lock); - -    /*Check if the hard link is present */ -    ctr_hard_link = ctr_search_hard_link_ctx(this, ctr_xlator_ctx, pgfid, -                                             base_name); -    if (!ctr_hard_link) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_HARDLINK_MISSING_IN_LIST, -               "Hard link doesn't exist in the list"); -        goto out; -    } - -    __delete_hard_link_from_list(&ctr_hard_link); -    ctr_hard_link = NULL; - -    ret = 0; -out: -    UNLOCK(&ctr_xlator_ctx->lock); - -    return ret; -} - -int -ctr_update_hard_link(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                     uuid_t pgfid, const char *base_name, uuid_t old_pgfid, -                     const char *old_base_name) -{ -    int ret = -1; -    ctr_hard_link_t *ctr_hard_link = NULL; -    struct timeval current_time = {0}; - -    GF_ASSERT(this); -    GF_ASSERT(ctr_xlator_ctx); - -    LOCK(&ctr_xlator_ctx->lock); - -    /*Check if the hard link is present */ -    ctr_hard_link = ctr_search_hard_link_ctx(this, ctr_xlator_ctx, old_pgfid, -                                             old_base_name); -    if (!ctr_hard_link) { -        gf_msg_trace(this->name, 0, -                     "Hard link doesn't exist" -                     " in the list"); -        /* Since the hard link is not present in the list -         * we add it to the list */ -        ret = ctr_add_hard_link(this, ctr_xlator_ctx, pgfid, base_name); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, 0, -                   CTR_MSG_ADD_HARDLINK_TO_LIST_FAILED, -                   "Failed adding hard link to the list"); -            goto out; -        } -        ret = 0; -        goto out; -    } - -    /* update the hard link */ -    gf_uuid_copy(ctr_hard_link->pgfid, pgfid); -    GF_FREE(ctr_hard_link->base_name); -    ret = gf_asprintf(&ctr_hard_link->base_name, "%s", base_name); -    if (ret < 0) { -        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_COPY_FAILED, -               "Failed copying basename" -               "to ctr_hard_link"); -        /* delete the corrupted entry */ -        __delete_hard_link_from_list(&ctr_hard_link); -        ctr_hard_link = NULL; -        goto out; -    } - -    ret = gettimeofday(¤t_time, NULL); -    if (ret == -1) { -        gf_log(this->name, GF_LOG_ERROR, "Failed to get current time"); -        ctr_hard_link->hardlink_heal_period = 0; -    } else { -        ctr_hard_link->hardlink_heal_period = current_time.tv_sec; -    } - -    ret = 0; - -out: -    UNLOCK(&ctr_xlator_ctx->lock); - -    return ret; -} - -/* Delete all hardlinks */ -static int -ctr_delete_all_hard_link(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx) -{ -    int ret = -1; -    ctr_hard_link_t *ctr_hard_link = NULL; -    ctr_hard_link_t *tmp = NULL; - -    GF_ASSERT(ctr_xlator_ctx); - -    LOCK(&ctr_xlator_ctx->lock); - -    list_for_each_entry_safe(ctr_hard_link, tmp, &ctr_xlator_ctx->hardlink_list, -                             list) -    { -        /*Remove hard link from list*/ -        __delete_hard_link_from_list(&ctr_hard_link); -        ctr_hard_link = NULL; -    } - -    UNLOCK(&ctr_xlator_ctx->lock); - -    ret = 0; - -    return ret; -} - -/* Please lock the inode before using this function */ -static ctr_xlator_ctx_t * -__get_ctr_xlator_ctx(xlator_t *this, inode_t *inode) -{ -    int ret = 0; -    uint64_t _addr = 0; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; - -    GF_ASSERT(this); -    GF_ASSERT(inode); - -    ret = __inode_ctx_get(inode, this, &_addr); -    if (ret < 0) -        _addr = 0; -    if (_addr != 0) { -        ctr_xlator_ctx = (ctr_xlator_ctx_t *)(long)_addr; -    } - -    return ctr_xlator_ctx; -} - -ctr_xlator_ctx_t * -init_ctr_xlator_ctx(xlator_t *this, inode_t *inode) -{ -    int ret = -1; -    uint64_t _addr = 0; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; -    struct timeval current_time = {0}; - -    GF_ASSERT(this); -    GF_ASSERT(inode); - -    LOCK(&inode->lock); -    { -        ctr_xlator_ctx = __get_ctr_xlator_ctx(this, inode); -        if (ctr_xlator_ctx) { -            ret = 0; -            goto out; -        } -        ctr_xlator_ctx = GF_CALLOC(1, sizeof(*ctr_xlator_ctx), -                                   gf_ctr_mt_xlator_ctx); -        if (!ctr_xlator_ctx) -            goto out; - -        ret = LOCK_INIT(&ctr_xlator_ctx->lock); -        if (ret) { -            gf_msg(this->name, GF_LOG_ERROR, ret, CTR_MSG_INIT_LOCK_FAILED, -                   "Failed init lock %s", strerror(ret)); -            goto out; -        } -        _addr = (uint64_t)(uintptr_t)ctr_xlator_ctx; - -        ret = __inode_ctx_set(inode, this, &_addr); -        if (ret) { -            goto out; -        } - -        INIT_LIST_HEAD(&ctr_xlator_ctx->hardlink_list); - -        ret = gettimeofday(¤t_time, NULL); -        if (ret == -1) { -            gf_log(this->name, GF_LOG_ERROR, "Failed to get current time"); -            goto out; -        } - -        ctr_xlator_ctx->inode_heal_period = current_time.tv_sec; -    } -    ret = 0; -out: -    if (ret) { -        GF_FREE(ctr_xlator_ctx); -        ctr_xlator_ctx = NULL; -    } - -    UNLOCK(&inode->lock); - -    return ctr_xlator_ctx; -} - -void -fini_ctr_xlator_ctx(xlator_t *this, inode_t *inode) -{ -    int ret = 0; -    uint64_t _addr = 0; -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; - -    inode_ctx_del(inode, this, &_addr); -    if (!_addr) -        return; - -    ctr_xlator_ctx = (ctr_xlator_ctx_t *)(long)_addr; - -    ret = ctr_delete_all_hard_link(this, ctr_xlator_ctx); -    if (ret) { -        gf_msg(this->name, GF_LOG_WARNING, 0, CTR_MSG_DELETE_HARDLINK_FAILED, -               "Failed deleting all " -               "hard links from inode context"); -    } - -    LOCK_DESTROY(&ctr_xlator_ctx->lock); - -    GF_FREE(ctr_xlator_ctx); -} - -ctr_xlator_ctx_t * -get_ctr_xlator_ctx(xlator_t *this, inode_t *inode) -{ -    ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; - -    LOCK(&inode->lock); -    ctr_xlator_ctx = __get_ctr_xlator_ctx(this, inode); -    UNLOCK(&inode->lock); - -    return ctr_xlator_ctx; -} diff --git a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.h b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.h deleted file mode 100644 index 4e3bf7e2798..00000000000 --- a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#ifndef __CTR_XLATOR_CTX_H -#define __CTR_XLATOR_CTX_H - -#include <glusterfs/xlator.h> -#include "ctr_mem_types.h" -#include <glusterfs/iatt.h> -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/locking.h> -#include <glusterfs/common-utils.h> -#include <time.h> -#include <sys/time.h> - -typedef struct ctr_hard_link { -    uuid_t pgfid; -    char *base_name; -    /* Hardlink expiry : Defines the expiry period after which a -     * database heal is attempted. */ -    uint64_t hardlink_heal_period; -    struct list_head list; -} ctr_hard_link_t; - -typedef struct ctr_xlator_ctx { -    /* This represents the looked up hardlinks -     * NOTE: This doesn't represent all physical hardlinks of the inode*/ -    struct list_head hardlink_list; -    uint64_t inode_heal_period; -    gf_lock_t lock; -} ctr_xlator_ctx_t; - -ctr_hard_link_t * -ctr_search_hard_link_ctx(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                         uuid_t pgfid, const char *base_name); - -int -ctr_add_hard_link(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                  uuid_t pgfid, const char *base_name); - -int -ctr_delete_hard_link(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                     uuid_t pgfid, const char *base_name); - -int -ctr_update_hard_link(xlator_t *this, ctr_xlator_ctx_t *ctr_xlator_ctx, -                     uuid_t pgfid, const char *base_name, uuid_t old_pgfid, -                     const char *old_base_name); - -ctr_xlator_ctx_t * -get_ctr_xlator_ctx(xlator_t *this, inode_t *inode); - -ctr_xlator_ctx_t * -init_ctr_xlator_ctx(xlator_t *this, inode_t *inode); - -void -fini_ctr_xlator_ctx(xlator_t *this, inode_t *inode); - -#endif diff --git a/xlators/features/changetimerecorder/src/ctr_mem_types.h b/xlators/features/changetimerecorder/src/ctr_mem_types.h deleted file mode 100644 index 7b8f531ddec..00000000000 --- a/xlators/features/changetimerecorder/src/ctr_mem_types.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -  Copyright (c) 2008-2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __CTR_MEM_TYPES_H__ -#define __CTR_MEM_TYPES_H__ - -#include "gfdb_mem-types.h" - -enum gf_ctr_mem_types_ { -    gf_ctr_mt_private_t = gfdb_mt_end + 1, -    gf_ctr_mt_xlator_ctx, -    gf_ctr_mt_hard_link_t, -    gf_ctr_mt_end -}; -#endif diff --git a/xlators/features/glupy/Makefile.am b/xlators/features/glupy/Makefile.am deleted file mode 100644 index 060429ecf0f..00000000000 --- a/xlators/features/glupy/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src examples - -CLEANFILES = diff --git a/xlators/features/glupy/doc/README.md b/xlators/features/glupy/doc/README.md deleted file mode 100644 index 4b8b863ef39..00000000000 --- a/xlators/features/glupy/doc/README.md +++ /dev/null @@ -1,44 +0,0 @@ -This is just the very start for a GlusterFS[1] meta-translator that will -allow translator code to be written in Python.  It's based on the standard -Python embedding (not extending) techniques, plus a dash of the ctypes module. -The interface is a pretty minimal adaptation of the dispatches and callbacks -from the C API[2] to Python, as follows: - -* Dispatch functions and callbacks must be defined on an "xlator" class -  derived from gluster.Translator so that they'll be auto-registered with -  the C translator during initialization. - -* For each dispatch or callback function you want to intercept, you define a -  Python function using the xxx\_fop\_t or xxx\_cbk\_t decorator. - -* The arguments for each operation are different, so you'll need to refer to -  the C API.  GlusterFS-specific types are used (though only loc\_t is fully -  defined so far) and type correctness is enforced by ctypes. - -* If you do intercept a dispatch function, it is your responsibility to call -  xxx\_wind (like STACK\_WIND in the C API but operation-specific) to pass -  the request to the next translator.  If you do not intercept a function, it -  will default the same way as for C (pass through to the same operation with -  the same arguments on the first child translator). - -* If you intercept a callback function, it is your responsibility to call -  xxx\_unwind (like STACK\_UNWIND\_STRICT in the C API) to pass the request back -  to the caller. - -So far only the lookup and create operations are handled this way, to support -the "negative lookup" example.  Now that the basic infrastructure is in place, -adding more functions should be very quick, though with that much boilerplate I -might pause to write a code generator.  I also plan to add structure -definitions and interfaces for some of the utility functions in libglusterfs -(especially those having to do with inode and fd context) in the fairly near -future.  Note that you can also use ctypes to get at anything not explicitly -exposed to Python already. - -_If you're coming here because of the Linux Journal article, please note that -the code has evolved since that was written. The version that matches the -article is here:_ - -https://github.com/jdarcy/glupy/tree/4bbae91ba459ea46ef32f2966562492e4ca9187a - -[1] http://www.gluster.org -[2] http://pl.atyp.us/hekafs.org/dist/xlator_api_2.html diff --git a/xlators/features/glupy/doc/TESTING b/xlators/features/glupy/doc/TESTING deleted file mode 100644 index e05f17f498f..00000000000 --- a/xlators/features/glupy/doc/TESTING +++ /dev/null @@ -1,9 +0,0 @@ -Loading a translator written in Python using the glupy meta translator -------------------------------------------------------------------------------- -'test.vol' is a simple volfile with the debug-trace Python translator on top -of a brick. The volfile can be mounted using the following command. - -$ glusterfs --debug -f test.vol /path/to/mntpt - -If then file operations are performed on the newly mounted file system, log -output would be printed by the Python translator on the standard output. diff --git a/xlators/features/glupy/doc/test.vol b/xlators/features/glupy/doc/test.vol deleted file mode 100644 index 0751a488c1f..00000000000 --- a/xlators/features/glupy/doc/test.vol +++ /dev/null @@ -1,10 +0,0 @@ -volume vol-posix -    type storage/posix -    option directory /path/to/brick -end-volume - -volume vol-glupy -    type features/glupy -    option module-name debug-trace -    subvolumes vol-posix -end-volume diff --git a/xlators/features/glupy/examples/Makefile.am b/xlators/features/glupy/examples/Makefile.am deleted file mode 100644 index c26abeaafb6..00000000000 --- a/xlators/features/glupy/examples/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features - -glupyexamplesdir = $(xlatordir)/glupy - -glupyexamples_PYTHON = negative.py helloworld.py debug-trace.py diff --git a/xlators/features/glupy/examples/debug-trace.py b/xlators/features/glupy/examples/debug-trace.py deleted file mode 100644 index 6e012f6c547..00000000000 --- a/xlators/features/glupy/examples/debug-trace.py +++ /dev/null @@ -1,777 +0,0 @@ - -from __future__ import print_function -import sys -import stat -from uuid import UUID -from time import strftime, localtime -from gluster.glupy import * - -# This translator was written primarily to test the fop entry point definitions -# and structure definitions in 'glupy.py'. - -# It is similar to the C language debug-trace translator, which logs the -# arguments passed to the fops and their corresponding cbk functions. - -dl.get_id.restype = c_long -dl.get_id.argtypes = [ POINTER(call_frame_t) ] - -dl.get_rootunique.restype = c_uint64 -dl.get_rootunique.argtypes = [ POINTER(call_frame_t) ] - -def uuid2str (gfid): -        return str(UUID(''.join(map("{0:02x}".format, gfid)))) - - -def st_mode_from_ia (prot, filetype): -        st_mode = 0 -        type_bit = 0 -        prot_bit = 0 - -        if filetype == IA_IFREG: -                type_bit = stat.S_IFREG -        elif filetype == IA_IFDIR: -                type_bit = stat.S_IFDIR -        elif filetype == IA_IFLNK: -                type_bit = stat.S_IFLNK -        elif filetype == IA_IFBLK: -                type_bit = stat.S_IFBLK -        elif filetype == IA_IFCHR: -                type_bit = stat.S_IFCHR -        elif filetype == IA_IFIFO: -                type_bit = stat.S_IFIFO -        elif filetype == IA_IFSOCK: -                type_bit = stat.S_IFSOCK -        elif filetype == IA_INVAL: -                pass - - -        if prot.suid: -                prot_bit |= stat.S_ISUID -        if prot.sgid: -                prot_bit |= stat.S_ISGID -        if prot.sticky: -                prot_bit |= stat.S_ISVTX - -        if prot.owner.read: -                prot_bit |= stat.S_IRUSR -        if prot.owner.write: -                prot_bit |= stat.S_IWUSR -        if prot.owner.execn: -                prot_bit |= stat.S_IXUSR - -        if prot.group.read: -                prot_bit |= stat.S_IRGRP -        if prot.group.write: -                prot_bit |= stat.S_IWGRP -        if prot.group.execn: -                prot_bit |= stat.S_IXGRP - -        if prot.other.read: -                prot_bit |= stat.S_IROTH -        if prot.other.write: -                prot_bit |= stat.S_IWOTH -        if prot.other.execn: -                prot_bit |= stat.S_IXOTH - -        st_mode = (type_bit | prot_bit) - -        return st_mode - - -def trace_stat2str (buf): -        gfid = uuid2str(buf.contents.ia_gfid) -        mode = st_mode_from_ia(buf.contents.ia_prot, buf.contents.ia_type) -        atime_buf = strftime("[%b %d %H:%M:%S]", -                             localtime(buf.contents.ia_atime)) -        mtime_buf = strftime("[%b %d %H:%M:%S]", -                             localtime(buf.contents.ia_mtime)) -        ctime_buf = strftime("[%b %d %H:%M:%S]", -                             localtime(buf.contents.ia_ctime)) -        return ("(gfid={0:s}, ino={1:d}, mode={2:o}, nlink={3:d}, uid ={4:d}, "+ -                "gid ={5:d}, size={6:d}, blocks={7:d}, atime={8:s}, mtime={9:s}, "+ -                "ctime={10:s})").format(gfid, buf.contents.ia_no, mode, -                                        buf.contents.ia_nlink, -                                        buf.contents.ia_uid, -                                        buf.contents.ia_gid, -                                        buf.contents.ia_size, -                                        buf.contents.ia_blocks, -                                        atime_buf, mtime_buf, -                                        ctime_buf) - -class xlator(Translator): - -        def __init__(self, c_this): -                Translator.__init__(self, c_this) -                self.gfids = {} - -        def lookup_fop(self, frame, this, loc, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.gfid) -                print(("GLUPY TRACE LOOKUP FOP- {0:d}: gfid={1:s}; " + -                      "path={2:s}").format(unique, gfid, loc.contents.path)) -                self.gfids[key] = gfid -                dl.wind_lookup(frame, POINTER(xlator_t)(), loc, xdata) -                return 0 - -        def lookup_cbk(self, frame, cookie, this, op_ret, op_errno, -                       inode, buf, xdata, postparent): -                unique =dl.get_rootunique(frame) -                key =dl.get_id(frame) -                if op_ret == 0: -                        gfid = uuid2str(buf.contents.ia_gfid) -                        statstr = trace_stat2str(buf) -                        postparentstr = trace_stat2str(postparent) -                        print(("GLUPY TRACE LOOKUP CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; *buf={3:s}; " + -                              "*postparent={4:s}").format(unique, gfid, -                                                          op_ret, statstr, -                                                          postparentstr)) -                else: -                        gfid = self.gfids[key] -                        print(("GLUPY TRACE LOOKUP CBK - {0:d}: gfid={1:s};" + -                              " op_ret={2:d}; op_errno={3:d}").format(unique, -                                                                      gfid, -                                                                      op_ret, -                                                                      op_errno)) -                del self.gfids[key] -                dl.unwind_lookup(frame, cookie, this, op_ret, op_errno, -                                 inode, buf, xdata, postparent) -                return 0 - -        def create_fop(self, frame, this, loc, flags, mode, umask, fd, -                       xdata): -                unique = dl.get_rootunique(frame) -                gfid = uuid2str(loc.contents.gfid) -                print(("GLUPY TRACE CREATE FOP- {0:d}: gfid={1:s}; path={2:s}; " + -                      "fd={3:s}; flags=0{4:o}; mode=0{5:o}; " + -                      "umask=0{6:o}").format(unique, gfid, loc.contents.path, -                                             fd, flags, mode, umask)) -                dl.wind_create(frame, POINTER(xlator_t)(), loc, flags, mode, -                               umask, fd, xdata) -                return 0 - -        def create_cbk(self, frame, cookie, this, op_ret, op_errno, fd, -                       inode, buf, preparent, postparent, xdata): -                unique = dl.get_rootunique(frame) -                if op_ret >= 0: -                        gfid = uuid2str(inode.contents.gfid) -                        statstr = trace_stat2str(buf) -                        preparentstr = trace_stat2str(preparent) -                        postparentstr = trace_stat2str(postparent) -                        print(("GLUPY TRACE CREATE CBK- {0:d}: gfid={1:s};" + -                              " op_ret={2:d}; fd={3:s}; *stbuf={4:s}; " + -                              "*preparent={5:s};" + -                              " *postparent={6:s}").format(unique, gfid, op_ret, -                                                           fd, statstr, -                                                           preparentstr, -                                                           postparentstr)) -                else: -                        print(("GLUPY TRACE CREATE CBK- {0:d}: op_ret={1:d}; " + -                              "op_errno={2:d}").format(unique, op_ret, op_errno)) -                dl.unwind_create(frame, cookie, this, op_ret, op_errno, fd, -                                 inode, buf, preparent, postparent, xdata) -                return 0 - -        def open_fop(self, frame, this, loc, flags, fd, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE OPEN FOP- {0:d}: gfid={1:s}; path={2:s}; "+ -                      "flags={3:d}; fd={4:s}").format(unique, gfid, -                                                      loc.contents.path, flags, -                                                      fd)) -                self.gfids[key] = gfid -                dl.wind_open(frame, POINTER(xlator_t)(), loc, flags, fd, xdata) -                return 0 - -        def open_cbk(self, frame, cookie, this, op_ret, op_errno, fd, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE OPEN CBK- {0:d}: gfid={1:s}; op_ret={2:d}; " -                      "op_errno={3:d}; *fd={4:s}").format(unique, gfid, -                                                          op_ret, op_errno, fd)) -                del self.gfids[key] -                dl.unwind_open(frame, cookie, this, op_ret, op_errno, fd, -                               xdata) -                return 0 - -        def readv_fop(self, frame, this, fd, size, offset, flags, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(fd.contents.inode.contents.gfid) -                print(("GLUPY TRACE READV FOP- {0:d}: gfid={1:s}; "+ -                      "fd={2:s}; size ={3:d}; offset={4:d}; " + -                      "flags=0{5:x}").format(unique, gfid, fd, size, offset, -                                             flags)) -                self.gfids[key] = gfid -                dl.wind_readv (frame, POINTER(xlator_t)(), fd, size, offset, -                               flags, xdata) -                return 0 - -        def readv_cbk(self, frame, cookie, this, op_ret, op_errno, vector, -                      count, buf, iobref, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                if op_ret >= 0: -                        statstr = trace_stat2str(buf) -                        print(("GLUPY TRACE READV CBK- {0:d}: gfid={1:s}, "+ -                              "op_ret={2:d}; *buf={3:s};").format(unique, gfid, -                                                                  op_ret, -                                                                  statstr)) - -                else: -                        print(("GLUPY TRACE READV CBK- {0:d}: gfid={1:s}, "+ -                              "op_ret={2:d}; op_errno={3:d}").format(unique, -                                                                     gfid, -                                                                     op_ret, -                                                                     op_errno)) -                del self.gfids[key] -                dl.unwind_readv (frame, cookie, this, op_ret, op_errno, -                                 vector, count, buf, iobref, xdata) -                return 0 - -        def writev_fop(self, frame, this, fd, vector, count, offset, flags, -                       iobref, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(fd.contents.inode.contents.gfid) -                print(("GLUPY TRACE  WRITEV FOP- {0:d}: gfid={1:s}; " + -                      "fd={2:s}; count={3:d}; offset={4:d}; " + -                      "flags=0{5:x}").format(unique, gfid, fd, count, offset, -                                             flags)) -                self.gfids[key] = gfid -                dl.wind_writev(frame, POINTER(xlator_t)(), fd, vector, count, -                               offset, flags, iobref, xdata) -                return 0 - -        def writev_cbk(self, frame, cookie, this, op_ret, op_errno, prebuf, -                       postbuf, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                if op_ret >= 0: -                        preopstr = trace_stat2str(prebuf) -                        postopstr = trace_stat2str(postbuf) -                        print(("GLUPY TRACE WRITEV CBK- {0:d}: op_ret={1:d}; " + -                              "*prebuf={2:s}; " + -                              "*postbuf={3:s}").format(unique, op_ret, preopstr, -                                                       postopstr)) -                else: -                        gfid = self.gfids[key] -                        print(("GLUPY TRACE WRITEV CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; op_errno={3:d}").format(unique, -                                                                     gfid, -                                                                     op_ret, -                                                                     op_errno)) -                del self.gfids[key] -                dl.unwind_writev (frame, cookie, this, op_ret, op_errno, -                                  prebuf, postbuf, xdata) -                return 0 - -        def opendir_fop(self, frame, this, loc, fd, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE OPENDIR FOP- {0:d}: gfid={1:s}; path={2:s}; "+ -                      "fd={3:s}").format(unique, gfid, loc.contents.path, fd)) -                self.gfids[key] = gfid -                dl.wind_opendir(frame, POINTER(xlator_t)(), loc, fd, xdata) -                return 0 - -        def opendir_cbk(self, frame, cookie, this, op_ret, op_errno, fd, -                        xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE OPENDIR CBK- {0:d}: gfid={1:s}; op_ret={2:d};"+ -                      " op_errno={3:d}; fd={4:s}").format(unique, gfid, op_ret, -                                                          op_errno, fd)) -                del self.gfids[key] -                dl.unwind_opendir(frame, cookie, this, op_ret, op_errno, -                                  fd, xdata) -                return 0 - -        def readdir_fop(self, frame, this, fd, size, offset, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(fd.contents.inode.contents.gfid) -                print(("GLUPY TRACE READDIR FOP- {0:d}:  gfid={1:s}; fd={2:s}; " + -                      "size={3:d}; offset={4:d}").format(unique, gfid, fd, size, -                                                         offset)) -                self.gfids[key] = gfid -                dl.wind_readdir(frame, POINTER(xlator_t)(), fd, size, offset, -                                xdata) -                return 0 - -        def readdir_cbk(self, frame, cookie, this, op_ret, op_errno, buf, -                        xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE READDIR CBK- {0:d}: gfid={1:s}; op_ret={2:d};"+ -                      " op_errno={3:d}").format(unique, gfid, op_ret, op_errno)) -                del self.gfids[key] -                dl.unwind_readdir(frame, cookie, this, op_ret, op_errno, buf, -                                  xdata) -                return 0 - -        def readdirp_fop(self, frame, this, fd, size, offset, dictionary): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(fd.contents.inode.contents.gfid) -                print(("GLUPY TRACE READDIRP FOP- {0:d}: gfid={1:s}; fd={2:s}; "+ -                      " size={3:d}; offset={4:d}").format(unique, gfid, fd, size, -                                                          offset)) -                self.gfids[key] = gfid -                dl.wind_readdirp(frame, POINTER(xlator_t)(), fd, size, offset, -                                 dictionary) -                return 0 - -        def readdirp_cbk(self, frame, cookie, this, op_ret, op_errno, buf, -                         xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE READDIRP CBK- {0:d}: gfid={1:s}; "+ -                      "op_ret={2:d}; op_errno={3:d}").format(unique, gfid, -                                                             op_ret, op_errno)) -                del self.gfids[key] -                dl.unwind_readdirp(frame, cookie, this, op_ret, op_errno, buf, -                                  xdata) -                return 0 - -        def mkdir_fop(self, frame, this, loc, mode, umask, xdata): -                unique = dl.get_rootunique(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE MKDIR FOP- {0:d}: gfid={1:s}; path={2:s}; " + -                      "mode={3:d}; umask=0{4:o}").format(unique, gfid, -                                                         loc.contents.path, mode, -                                                         umask)) -                dl.wind_mkdir(frame, POINTER(xlator_t)(), loc, mode, umask, -                              xdata) -                return 0 - -        def mkdir_cbk(self, frame, cookie, this, op_ret, op_errno, inode, buf, -                      preparent, postparent,  xdata): -                unique = dl.get_rootunique(frame) -                if op_ret == 0: -                        gfid = uuid2str(inode.contents.gfid) -                        statstr = trace_stat2str(buf) -                        preparentstr = trace_stat2str(preparent) -                        postparentstr = trace_stat2str(postparent) -                        print(("GLUPY TRACE MKDIR CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; *stbuf={3:s}; *prebuf={4:s}; "+ -                              "*postbuf={5:s} ").format(unique, gfid, op_ret, -                                                        statstr, -                                                        preparentstr, -                                                        postparentstr)) -                else: -                        print(("GLUPY TRACE MKDIR CBK- {0:d}:  op_ret={1:d}; "+ -                              "op_errno={2:d}").format(unique, op_ret, op_errno)) -                dl.unwind_mkdir(frame, cookie, this, op_ret, op_errno, inode, -                                buf, preparent, postparent, xdata) -                return 0 - -        def rmdir_fop(self, frame, this, loc, flags, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE RMDIR FOP- {0:d}: gfid={1:s}; path={2:s}; "+ -                      "flags={3:d}").format(unique, gfid, loc.contents.path, -                                            flags)) -                self.gfids[key] = gfid -                dl.wind_rmdir(frame, POINTER(xlator_t)(), loc, flags, xdata) -                return 0 - -        def rmdir_cbk(self, frame, cookie, this, op_ret, op_errno, preparent, -                      postparent, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                if op_ret == 0: -                        preparentstr = trace_stat2str(preparent) -                        postparentstr = trace_stat2str(postparent) -                        print(("GLUPY TRACE RMDIR CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; *prebuf={3:s}; "+ -                              "*postbuf={4:s}").format(unique, gfid, op_ret, -                                                       preparentstr, -                                                       postparentstr)) -                else: -                        print(("GLUPY TRACE RMDIR CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; op_errno={3:d}").format(unique, -                                                                     gfid, -                                                                     op_ret, -                                                                     op_errno)) -                del self.gfids[key] -                dl.unwind_rmdir(frame, cookie, this, op_ret, op_errno, -                                preparent, postparent, xdata) -                return 0 - -        def stat_fop(self, frame, this, loc, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE STAT FOP- {0:d}: gfid={1:s}; " + -                      " path={2:s}").format(unique, gfid, loc.contents.path)) -                self.gfids[key] = gfid -                dl.wind_stat(frame, POINTER(xlator_t)(), loc, xdata) -                return 0 - -        def stat_cbk(self, frame, cookie, this, op_ret, op_errno, buf, -                     xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                if op_ret == 0: -                        statstr = trace_stat2str(buf) -                        print(("GLUPY TRACE STAT CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d};  *buf={3:s};").format(unique, -                                                                   gfid, -                                                                   op_ret, -                                                                   statstr)) -                else: -                        print(("GLUPY TRACE STAT CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; op_errno={3:d}").format(unique, -                                                                     gfid, -                                                                     op_ret, -                                                                     op_errno)) -                del self.gfids[key] -                dl.unwind_stat(frame, cookie, this, op_ret, op_errno, -                               buf, xdata) -                return 0 - -        def fstat_fop(self, frame, this, fd, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(fd.contents.inode.contents.gfid) -                print(("GLUPY TRACE FSTAT FOP- {0:d}:  gfid={1:s}; " + -                      "fd={2:s}").format(unique, gfid, fd)) -                self.gfids[key] = gfid -                dl.wind_fstat(frame, POINTER(xlator_t)(), fd, xdata) -                return 0 - -        def fstat_cbk(self, frame, cookie, this, op_ret, op_errno, buf, -                      xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                if op_ret == 0: -                        statstr = trace_stat2str(buf) -                        print(("GLUPY TRACE FSTAT CBK- {0:d}: gfid={1:s} "+ -                              " op_ret={2:d}; *buf={3:s}").format(unique, -                                                                  gfid, -                                                                  op_ret, -                                                                  statstr)) -                else: -                        print(("GLUPY TRACE FSTAT CBK- {0:d}: gfid={1:s} "+ -                              "op_ret={2:d}; op_errno={3:d}").format(unique. -                                                                     gfid, -                                                                     op_ret, -                                                                     op_errno)) -                del self.gfids[key] -                dl.unwind_fstat(frame, cookie, this, op_ret, op_errno, -                                buf, xdata) -                return 0 - -        def statfs_fop(self, frame, this, loc, xdata): -                unique = dl.get_rootunique(frame) -                if loc.contents.inode: -                        gfid = uuid2str(loc.contents.inode.contents.gfid) -                else: -                        gfid = "0" -                print(("GLUPY TRACE STATFS FOP- {0:d}: gfid={1:s}; "+ -                      "path={2:s}").format(unique, gfid, loc.contents.path)) -                dl.wind_statfs(frame, POINTER(xlator_t)(), loc, xdata) -                return 0 - -        def statfs_cbk(self, frame, cookie, this, op_ret, op_errno, buf, -                       xdata): -                unique = dl.get_rootunique(frame) -                if op_ret == 0: -                        #TBD: print buf (pointer to an iovec type object) -                        print(("GLUPY TRACE STATFS CBK {0:d}: "+ -                              "op_ret={1:d}").format(unique, op_ret)) -                else: -                        print(("GLUPY TRACE STATFS CBK-  {0:d}"+ -                              "op_ret={1:d}; op_errno={2:d}").format(unique, -                                                                     op_ret, -                                                                     op_errno)) -                dl.unwind_statfs(frame, cookie, this, op_ret, op_errno, -                                 buf, xdata) -                return 0 - -        def getxattr_fop(self, frame, this, loc, name, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE GETXATTR FOP- {0:d}: gfid={1:s}; path={2:s};"+ -                      " name={3:s}").format(unique, gfid, loc.contents.path, -                                            name)) -                self.gfids[key]=gfid -                dl.wind_getxattr(frame, POINTER(xlator_t)(), loc, name, xdata) -                return 0 - -        def getxattr_cbk(self, frame, cookie, this, op_ret, op_errno, -                         dictionary, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE GETXATTR CBK- {0:d}: gfid={1:s}; "+ -                      "op_ret={2:d}; op_errno={3:d}; "+ -                      " dictionary={4:s}").format(unique, gfid, op_ret, op_errno, -                                                  dictionary)) -                del self.gfids[key] -                dl.unwind_getxattr(frame, cookie, this, op_ret, op_errno, -                                   dictionary, xdata) -                return 0 - -        def fgetxattr_fop(self, frame, this, fd, name, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(fd.contents.inode.contents.gfid) -                print(("GLUPY TRACE FGETXATTR FOP- {0:d}: gfid={1:s}; fd={2:s}; "+ -                      "name={3:s}").format(unique, gfid, fd, name)) -                self.gfids[key] = gfid -                dl.wind_fgetxattr(frame, POINTER(xlator_t)(), fd, name, xdata) -                return 0 - -        def fgetxattr_cbk(self, frame, cookie, this, op_ret, op_errno, -                          dictionary, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE FGETXATTR CBK- {0:d}: gfid={1:s}; "+ -                      "op_ret={2:d}; op_errno={3:d};"+ -                      " dictionary={4:s}").format(unique, gfid, op_ret, -                                                  op_errno, dictionary)) -                del self.gfids[key] -                dl.unwind_fgetxattr(frame, cookie, this, op_ret, op_errno, -                                    dictionary, xdata) -                return 0 - -        def setxattr_fop(self, frame, this, loc, dictionary, flags, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE SETXATTR FOP- {0:d}:  gfid={1:s}; path={2:s};"+ -                      " flags={3:d}").format(unique, gfid, loc.contents.path, -                                             flags)) -                self.gfids[key] = gfid -                dl.wind_setxattr(frame, POINTER(xlator_t)(), loc, dictionary, -                                 flags, xdata) -                return 0 - -        def setxattr_cbk(self, frame, cookie, this, op_ret, op_errno, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE SETXATTR CBK- {0:d}: gfid={1:s}; "+ -                      "op_ret={2:d}; op_errno={3:d}").format(unique, gfid, -                                                             op_ret, op_errno)) -                del self.gfids[key] -                dl.unwind_setxattr(frame, cookie, this, op_ret, op_errno, -                                   xdata) -                return 0 - -        def fsetxattr_fop(self, frame, this, fd, dictionary, flags, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(fd.contents.inode.contents.gfid) -                print(("GLUPY TRACE FSETXATTR FOP- {0:d}: gfid={1:s}; fd={2:p}; "+ -                      "flags={3:d}").format(unique, gfid, fd, flags)) -                self.gfids[key] = gfid -                dl.wind_fsetxattr(frame, POINTER(xlator_t)(), fd, dictionary, -                                  flags, xdata) -                return 0 - -        def fsetxattr_cbk(self, frame, cookie, this, op_ret, op_errno, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE FSETXATTR CBK- {0:d}: gfid={1:s};  "+ -                      "op_ret={2:d}; op_errno={3:d}").format(unique, gfid, -                                                             op_ret, op_errno)) -                del self.gfids[key] -                dl.unwind_fsetxattr(frame, cookie, this, op_ret, op_errno, -                                   xdata) -                return 0 - -        def removexattr_fop(self, frame, this, loc, name, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE REMOVEXATTR FOP- {0:d}:  gfid={1:s}; "+ -                      "path={2:s}; name={3:s}").format(unique, gfid, -                                                       loc.contents.path, -                                                       name)) -                self.gfids[key] = gfid -                dl.wind_removexattr(frame, POINTER(xlator_t)(), loc, name, -                                    xdata) -                return 0 - -        def removexattr_cbk(self, frame, cookie, this, op_ret, op_errno, -                            xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                print(("GLUPY TRACE REMOVEXATTR CBK- {0:d}: gfid={1:s} "+ -                      " op_ret={2:d}; op_errno={3:d}").format(unique, gfid, -                                                              op_ret, op_errno)) -                del self.gfids[key] -                dl.unwind_removexattr(frame, cookie, this, op_ret, op_errno, -                                      xdata) -                return 0 - -        def link_fop(self, frame, this, oldloc, newloc, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                if (newloc.contents.inode): -                        newgfid = uuid2str(newloc.contents.inode.contents.gfid) -                else: -                        newgfid = "0" -                oldgfid = uuid2str(oldloc.contents.inode.contents.gfid) -                print(("GLUPY TRACE LINK FOP-{0:d}: oldgfid={1:s}; oldpath={2:s};"+ -                      "newgfid={3:s};"+ -                      "newpath={4:s}").format(unique, oldgfid, -                                              oldloc.contents.path, -                                              newgfid, -                                              newloc.contents.path)) -                self.gfids[key] =  oldgfid -                dl.wind_link(frame, POINTER(xlator_t)(), oldloc, newloc, -                             xdata) -                return 0 - -        def link_cbk(self, frame, cookie, this, op_ret, op_errno, inode, buf, -                     preparent, postparent, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                if op_ret == 0: -                        statstr = trace_stat2str(buf) -                        preparentstr = trace_stat2str(preparent) -                        postparentstr = trace_stat2str(postparent) -                        print(("GLUPY TRACE LINK CBK- {0:d}: op_ret={1:d} "+ -                              "*stbuf={2:s}; *prebuf={3:s}; "+ -                              "*postbuf={4:s} ").format(unique, op_ret, statstr, -                                                        preparentstr, -                                                        postparentstr)) -                else: -                        print(("GLUPY TRACE LINK CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; "+ -                              "op_errno={3:d}").format(unique, gfid, -                                                       op_ret, op_errno)) -                del self.gfids[key] -                dl.unwind_link(frame, cookie, this, op_ret, op_errno, inode, -                               buf, preparent, postparent, xdata) -                return 0 - -        def unlink_fop(self, frame, this, loc, xflag, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE UNLINK FOP- {0:d}; gfid={1:s}; path={2:s}; "+ -                      "flag={3:d}").format(unique, gfid, loc.contents.path, -                                           xflag)) -                self.gfids[key] = gfid -                dl.wind_unlink(frame, POINTER(xlator_t)(), loc, xflag, -                               xdata) -                return 0 - -        def unlink_cbk(self, frame, cookie, this, op_ret, op_errno, -                       preparent, postparent, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                if op_ret == 0: -                        preparentstr = trace_stat2str(preparent) -                        postparentstr = trace_stat2str(postparent) -                        print(("GLUPY TRACE UNLINK CBK- {0:d}: gfid ={1:s}; "+ -                              "op_ret={2:d}; *prebuf={3:s}; "+ -                              "*postbuf={4:s} ").format(unique, gfid, op_ret, -                                                        preparentstr, -                                                        postparentstr)) -                else: -                        print(("GLUPY TRACE UNLINK CBK: {0:d}: gfid ={1:s}; "+ -                              "op_ret={2:d}; "+ -                              "op_errno={3:d}").format(unique, gfid, op_ret, -                                                       op_errno)) -                del self.gfids[key] -                dl.unwind_unlink(frame, cookie, this, op_ret, op_errno, -                                 preparent, postparent, xdata) -                return 0 - -        def readlink_fop(self, frame, this, loc, size, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE READLINK FOP- {0:d}:  gfid={1:s}; path={2:s};"+ -                      " size={3:d}").format(unique, gfid, loc.contents.path, -                                            size)) -                self.gfids[key] = gfid -                dl.wind_readlink(frame, POINTER(xlator_t)(), loc, size, -                               xdata) -                return 0 - -        def readlink_cbk(self, frame, cookie, this, op_ret, op_errno, -                         buf, stbuf, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid  = self.gfids[key] -                if op_ret == 0: -                        statstr = trace_stat2str(stbuf) -                        print(("GLUPY TRACE READLINK CBK- {0:d}: gfid={1:s} "+ -                              " op_ret={2:d}; op_errno={3:d}; *prebuf={4:s}; "+ -                              "*postbuf={5:s} ").format(unique, gfid, -                                                        op_ret, op_errno, -                                                        buf, statstr)) -                else: -                        print(("GLUPY TRACE READLINK CBK- {0:d}: gfid={1:s} "+ -                              " op_ret={2:d}; op_errno={3:d}").format(unique, -                                                                      gfid, -                                                                      op_ret, -                                                                      op_errno)) -                del self.gfids[key] -                dl.unwind_readlink(frame, cookie, this, op_ret, op_errno, buf, -                                   stbuf, xdata) -                return 0 - -        def symlink_fop(self, frame, this, linkpath, loc, umask, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = uuid2str(loc.contents.inode.contents.gfid) -                print(("GLUPY TRACE SYMLINK FOP- {0:d}: gfid={1:s}; "+ -                      "linkpath={2:s}; path={3:s};"+ -                      "umask=0{4:o}").format(unique, gfid, linkpath, -                                             loc.contents.path, umask)) -                self.gfids[key] = gfid -                dl.wind_symlink(frame, POINTER(xlator_t)(), linkpath, loc, -                                umask, xdata) -                return 0 - -        def symlink_cbk(self, frame, cookie, this, op_ret, op_errno, -                        inode, buf, preparent, postparent, xdata): -                unique = dl.get_rootunique(frame) -                key = dl.get_id(frame) -                gfid = self.gfids[key] -                if op_ret == 0: -                        statstr = trace_stat2str(buf) -                        preparentstr = trace_stat2str(preparent) -                        postparentstr = trace_stat2str(postparent) -                        print(("GLUPY TRACE SYMLINK CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; *stbuf={3:s}; *preparent={4:s}; "+ -                              "*postparent={5:s}").format(unique, gfid, -                                                          op_ret, statstr, -                                                          preparentstr, -                                                          postparentstr)) -                else: -                        print(("GLUPY TRACE SYMLINK CBK- {0:d}: gfid={1:s}; "+ -                              "op_ret={2:d}; op_errno={3:d}").format(unique, -                                                                     gfid, -                                                                     op_ret, -                                                                     op_errno)) -                del self.gfids[key] -                dl.unwind_symlink(frame, cookie, this, op_ret, op_errno, -                                  inode, buf, preparent, postparent, xdata) -                return 0 diff --git a/xlators/features/glupy/examples/helloworld.py b/xlators/features/glupy/examples/helloworld.py deleted file mode 100644 index 282f9207949..00000000000 --- a/xlators/features/glupy/examples/helloworld.py +++ /dev/null @@ -1,21 +0,0 @@ - -from __future__ import print_function -import sys -from gluster.glupy import * - -class xlator (Translator): - -    def __init__(self, c_this): -        Translator.__init__(self, c_this) - -    def lookup_fop(self, frame, this, loc, xdata): -        print("Python xlator: Hello!") -        dl.wind_lookup(frame, POINTER(xlator_t)(), loc, xdata) -        return 0 - -    def lookup_cbk(self, frame, cookie, this, op_ret, op_errno, inode, buf, -                   xdata, postparent): -        print("Python xlator: Hello again!") -        dl.unwind_lookup(frame, cookie, this, op_ret, op_errno, inode, buf, -                         xdata, postparent) -        return 0 diff --git a/xlators/features/glupy/examples/negative.py b/xlators/features/glupy/examples/negative.py deleted file mode 100644 index e04b16aa553..00000000000 --- a/xlators/features/glupy/examples/negative.py +++ /dev/null @@ -1,93 +0,0 @@ - -from __future__ import print_function -import sys -from uuid import UUID -from gluster.glupy import * - -# Negative-lookup-caching example.  If a file wasn't there the last time we -# looked, it's probably still not there.  This translator keeps track of -# those failed lookups for us, and returns ENOENT without needing to pass the -# call any further for repeated requests. - -# If we were doing this for real, we'd need separate caches for each xlator -# instance.  The easiest way to do this would be to have xlator.__init__ -# "register" each instance in a module-global dict, with the key as the C -# translator address and the value as the xlator object itself.  For testing -# and teaching, it's sufficient just to have one cache.  The keys are parent -# GFIDs, and the entries are lists of names within that parent that we know -# don't exist. -cache = {} - -# TBD: we need a better way of handling per-request data (frame->local in C). -dl.get_id.restype = c_long -dl.get_id.argtypes = [ POINTER(call_frame_t) ] - -def uuid2str (gfid): -    return str(UUID(''.join(map("{0:02x}".format, gfid)))) - -class xlator (Translator): - -    def __init__ (self, c_this): -        self.requests = {} -        Translator.__init__(self, c_this) - -    def lookup_fop (self, frame, this, loc, xdata): -        pargfid = uuid2str(loc.contents.pargfid) -        print("lookup FOP: %s:%s" % (pargfid, loc.contents.name)) -        # Check the cache. -        if pargfid in cache: -            if loc.contents.name in cache[pargfid]: -                print("short-circuiting for %s:%s" % (pargfid, -                    loc.contents.name)) -                dl.unwind_lookup(frame, 0, this, -1, 2, None, None, None, None) -                return 0 -        key = dl.get_id(frame) -        self.requests[key] = (pargfid, loc.contents.name[:]) -        # TBD: get real child xl from init, pass it here -        dl.wind_lookup(frame, POINTER(xlator_t)(), loc, xdata) -        return 0 - -    def lookup_cbk (self, frame, cookie, this, op_ret, op_errno, inode, buf, -                    xdata, postparent): -        print("lookup CBK: %d (%d)" % (op_ret, op_errno)) -        key = dl.get_id(frame) -        pargfid, name = self.requests[key] -        # Update the cache. -        if op_ret == 0: -            print("found %s, removing from cache" % name) -            if pargfid in cache: -                cache[pargfid].discard(name) -        elif op_errno == 2:    # ENOENT -            print("failed to find %s, adding to cache" % name) -            if pargfid in cache: -                cache[pargfid].add(name) -            else: -                cache[pargfid] = {name} -        del self.requests[key] -        dl.unwind_lookup(frame, cookie, this, op_ret, op_errno, -                         inode, buf, xdata, postparent) -        return 0 - -    def create_fop (self, frame, this, loc, flags, mode, umask, fd, xdata): -        pargfid = uuid2str(loc.contents.pargfid) -        print("create FOP: %s:%s" % (pargfid, loc.contents.name)) -        key = dl.get_id(frame) -        self.requests[key] = (pargfid, loc.contents.name[:]) -        # TBD: get real child xl from init, pass it here -        dl.wind_create(frame, POINTER(xlator_t)(), loc, flags, mode, umask, fd, xdata) -        return 0 - -    def create_cbk (self, frame, cookie, this, op_ret, op_errno, fd, inode, -                    buf, preparent, postparent, xdata): -        print("create CBK: %d (%d)" % (op_ret, op_errno)) -        key = dl.get_id(frame) -        pargfid, name = self.requests[key] -        # Update the cache. -        if op_ret == 0: -            print("created %s, removing from cache" % name) -            if pargfid in cache: -                cache[pargfid].discard(name) -        del self.requests[key] -        dl.unwind_create(frame, cookie, this, op_ret, op_errno, fd, inode, buf, -                         preparent, postparent, xdata) -        return 0 diff --git a/xlators/features/glupy/src/Makefile.am b/xlators/features/glupy/src/Makefile.am deleted file mode 100644 index 817b0d00f61..00000000000 --- a/xlators/features/glupy/src/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -xlator_LTLIBRARIES = glupy.la - -# Ensure GLUSTER_PYTHON_PATH is passed to glupy.so -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features -glupydir = $(xlatordir)/glupy - -AM_CPPFLAGS = $(GF_CPPFLAGS) \ -	-I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src - -AM_CFLAGS = -Wall -fno-strict-aliasing \ -	-DGLUSTER_PYTHON_PATH=\"$(glupydir)\" \ -	-DPATH_GLUSTERFS_GLUPY_MODULE=\"${xlatordir}/glupy${shrext_cmds}\" \ -	$(GF_CFLAGS) $(PYTHON_CFLAGS) - -# Flags to build glupy.so with -glupy_la_LDFLAGS = -module -nostartfiles \ -        -export-symbols $(top_srcdir)/xlators/features/glupy/src/glupy.sym \ -        $(GF_XLATOR_LDFLAGS) $(PYTHON_LIBS) - -glupy_la_SOURCES = glupy.c -glupy_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ -	-lpthread $(LIB_DL) - -noinst_HEADERS = glupy.h - -# Install __init__.py into the Python site-packages area -pyglupydir = @BUILD_PYTHON_SITE_PACKAGES@/gluster -pyglupy_PYTHON = __init__.py - -# Install glupy/__init_-.py into the Python site-packages area -SUBDIRS = glupy - -CLEANFILES = - -EXTRA_DIST = glupy.sym diff --git a/xlators/features/glupy/src/__init__.py.in b/xlators/features/glupy/src/__init__.py.in deleted file mode 100644 index 3ad9513f40e..00000000000 --- a/xlators/features/glupy/src/__init__.py.in +++ /dev/null @@ -1,2 +0,0 @@ -from pkgutil import extend_path -__path__ = extend_path(__path__, __name__) diff --git a/xlators/features/glupy/src/glupy.c b/xlators/features/glupy/src/glupy.c deleted file mode 100644 index e2241b49ad3..00000000000 --- a/xlators/features/glupy/src/glupy.c +++ /dev/null @@ -1,2446 +0,0 @@ -/* -   Copyright (c) 2006-2014 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#include <ctype.h> -#include <dlfcn.h> -#include <sys/uio.h> -#include <Python.h> - -#include <glusterfs/glusterfs.h> -#include <glusterfs/xlator.h> -#include <glusterfs/logging.h> -#include <glusterfs/defaults.h> - -#include "glupy.h" - -/* UTILITY FUNCTIONS FOR FOP-SPECIFIC CODE */ - -pthread_key_t gil_init_key; - -PyGILState_STATE -glupy_enter(void) -{ -    if (!pthread_getspecific(gil_init_key)) { -        PyEval_ReleaseLock(); -        (void)pthread_setspecific(gil_init_key, (void *)1); -    } - -    return PyGILState_Ensure(); -} - -void -glupy_leave(PyGILState_STATE gstate) -{ -    PyGILState_Release(gstate); -} - -/* FOP: LOOKUP */ - -int32_t -glupy_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, inode_t *inode, -                 struct iatt *buf, dict_t *xdata, struct iatt *postparent) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_LOOKUP]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_lookup_cbk_t)(priv->cbks[GLUPY_LOOKUP]))( -        frame, cookie, this, op_ret, op_errno, inode, buf, xdata, postparent); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, -                        postparent); -    return 0; -} - -int32_t -glupy_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_LOOKUP]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_lookup_t)(priv->fops[GLUPY_LOOKUP]))(frame, this, loc, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_lookup_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lookup, loc, xdata); -    return 0; -} - -void -wind_lookup(call_frame_t *frame, xlator_t *xl, loc_t *loc, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_lookup_cbk, xl, xl->fops->lookup, loc, xdata); -} - -void -unwind_lookup(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, -              struct iatt *postparent) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, -                        postparent); -} - -void -set_lookup_fop(long py_this, fop_lookup_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_LOOKUP] = (long)fop; -} - -void -set_lookup_cbk(long py_this, fop_lookup_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_LOOKUP] = (long)cbk; -} - -/* FOP: CREATE */ - -int32_t -glupy_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, -                 struct iatt *buf, struct iatt *preparent, -                 struct iatt *postparent, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_CREATE]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_create_cbk_t)(priv->cbks[GLUPY_CREATE]))( -        frame, cookie, this, op_ret, op_errno, fd, inode, buf, preparent, -        postparent, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, -                        preparent, postparent, xdata); -    return 0; -} - -int32_t -glupy_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -             mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_CREATE]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_create_t)(priv->fops[GLUPY_CREATE]))(frame, this, loc, flags, -                                                     mode, umask, fd, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_create_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, -               xdata); -    return 0; -} - -void -wind_create(call_frame_t *frame, xlator_t *xl, loc_t *loc, int32_t flags, -            mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_create_cbk, xl, xl->fops->create, loc, flags, mode, -               umask, fd, xdata); -} - -void -unwind_create(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, -              struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, -                        preparent, postparent, xdata); -} - -void -set_create_fop(long py_this, fop_create_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_CREATE] = (long)fop; -} - -void -set_create_cbk(long py_this, fop_create_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_CREATE] = (long)cbk; -} - -/* FOP: OPEN */ - -int32_t -glupy_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_OPEN]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_open_cbk_t)(priv->cbks[GLUPY_OPEN]))( -        frame, cookie, this, op_ret, op_errno, fd, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); -    return 0; -} - -int32_t -glupy_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -           fd_t *fd, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_OPEN]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_open_t)(priv->fops[GLUPY_OPEN]))(frame, this, loc, flags, fd, -                                                 xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_open_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); -    return 0; -} - -void -wind_open(call_frame_t *frame, xlator_t *xl, loc_t *loc, int32_t flags, -          fd_t *fd, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_open_cbk, xl, xl->fops->open, loc, flags, fd, -               xdata); -} - -void -unwind_open(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -            int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); -} - -void -set_open_fop(long py_this, fop_open_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; -    priv->fops[GLUPY_OPEN] = (long)fop; -} - -void -set_open_cbk(long py_this, fop_open_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; -    priv->cbks[GLUPY_OPEN] = (long)cbk; -} - -/* FOP: READV */ - -int32_t -glupy_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, struct iovec *vector, -                int32_t count, struct iatt *stbuf, struct iobref *iobref, -                dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_READV]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_readv_cbk_t)(priv->cbks[GLUPY_READV]))( -        frame, cookie, this, op_ret, op_errno, vector, count, stbuf, iobref, -        xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf, -                        iobref, xdata); -    return 0; -} - -int32_t -glupy_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -            off_t offset, uint32_t flags, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_READV]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_readv_t)(priv->fops[GLUPY_READV]))(frame, this, fd, size, -                                                   offset, flags, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_readv_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); -    return 0; -} - -void -wind_readv(call_frame_t *frame, xlator_t *xl, fd_t *fd, size_t size, -           off_t offset, uint32_t flags, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_readv_cbk, xl, xl->fops->readv, fd, size, offset, -               flags, xdata); -} - -void -unwind_readv(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, struct iovec *vector, int32_t count, -             struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf, -                        iobref, xdata); -} - -void -set_readv_fop(long py_this, fop_readv_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; -    priv->fops[GLUPY_READV] = (long)fop; -} - -void -set_readv_cbk(long py_this, fop_readv_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; -    priv->cbks[GLUPY_READV] = (long)cbk; -} - -/* FOP: WRITEV */ - -int32_t -glupy_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                 struct iatt *postbuf, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_WRITEV]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_writev_cbk_t)(priv->cbks[GLUPY_WRITEV]))( -        frame, cookie, this, op_ret, op_errno, prebuf, postbuf, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, -                        xdata); -    return 0; -} - -int32_t -glupy_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, -             struct iovec *vector, int32_t count, off_t offset, uint32_t flags, -             struct iobref *iobref, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_WRITEV]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_writev_t)(priv->fops[GLUPY_WRITEV]))( -        frame, this, fd, vector, count, offset, flags, iobref, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_writev_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, -               flags, iobref, xdata); -    return 0; -} - -void -wind_writev(call_frame_t *frame, xlator_t *xl, fd_t *fd, struct iovec *vector, -            int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, -            dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_writev_cbk, xl, xl->fops->writev, fd, vector, count, -               offset, flags, iobref, xdata); -} - -void -unwind_writev(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, -              dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, -                        xdata); -} - -void -set_writev_fop(long py_this, fop_writev_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; -    priv->fops[GLUPY_WRITEV] = (long)fop; -} - -void -set_writev_cbk(long py_this, fop_writev_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; -    priv->cbks[GLUPY_WRITEV] = (long)cbk; -} - -/* FOP: OPENDIR */ - -int32_t -glupy_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_OPENDIR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_opendir_cbk_t)(priv->cbks[GLUPY_OPENDIR]))( -        frame, cookie, this, op_ret, op_errno, fd, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, xdata); -    return 0; -} - -int32_t -glupy_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, -              dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_OPENDIR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_opendir_t)(priv->fops[GLUPY_OPENDIR]))(frame, this, loc, fd, -                                                       xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_opendir_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); -    return 0; -} - -void -wind_opendir(call_frame_t *frame, xlator_t *xl, loc_t *loc, fd_t *fd, -             dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_opendir_cbk, xl, xl->fops->opendir, loc, fd, xdata); -} - -void -unwind_opendir(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -               int32_t op_errno, fd_t *fd, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, xdata); -} - -void -set_opendir_fop(long py_this, fop_opendir_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_OPENDIR] = (long)fop; -} - -void -set_opendir_cbk(long py_this, fop_opendir_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_OPENDIR] = (long)cbk; -} - -/* FOP: READDIR */ - -int32_t -glupy_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, -                  dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_READDIR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_readdir_cbk_t)(priv->cbks[GLUPY_READDIR]))( -        frame, cookie, this, op_ret, op_errno, entries, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(readdir, frame, op_ret, op_errno, entries, xdata); -    return 0; -} - -int32_t -glupy_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -              off_t offset, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_READDIR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_readdir_t)(priv->fops[GLUPY_READDIR]))(frame, this, fd, size, -                                                       offset, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_readdir_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); -    return 0; -} - -void -wind_readdir(call_frame_t *frame, xlator_t *xl, fd_t *fd, size_t size, -             off_t offset, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_readdir_cbk, xl, xl->fops->readdir, fd, size, -               offset, xdata); -} - -void -unwind_readdir(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -               int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(readdir, frame, op_ret, op_errno, entries, xdata); -} - -void -set_readdir_fop(long py_this, fop_readdir_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_READDIR] = (long)fop; -} - -void -set_readdir_cbk(long py_this, fop_readdir_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_READDIR] = (long)cbk; -} - -/* FOP: READDIRP */ - -int32_t -glupy_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, -                   dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_READDIRP]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_readdirp_cbk_t)(priv->cbks[GLUPY_READDIRP]))( -        frame, cookie, this, op_ret, op_errno, entries, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata); -    return 0; -} - -int32_t -glupy_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -               off_t offset, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_READDIRP]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_readdirp_t)(priv->fops[GLUPY_READDIRP]))(frame, this, fd, size, -                                                         offset, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_readdirp_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readdirp, fd, size, offset, xdata); -    return 0; -} - -void -wind_readdirp(call_frame_t *frame, xlator_t *xl, fd_t *fd, size_t size, -              off_t offset, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_readdirp_cbk, xl, xl->fops->readdirp, fd, size, -               offset, xdata); -} - -void -unwind_readdirp(call_frame_t *frame, long cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, -                dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata); -} - -void -set_readdirp_fop(long py_this, fop_readdirp_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_READDIRP] = (long)fop; -} - -void -set_readdirp_cbk(long py_this, fop_readdirp_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_READDIRP] = (long)cbk; -} - -/* FOP:STAT */ - -int32_t -glupy_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, struct iatt *buf, -               dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_STAT]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_stat_cbk_t)(priv->cbks[GLUPY_STAT]))( -        frame, cookie, this, op_ret, op_errno, buf, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, buf, xdata); -    return 0; -} - -int32_t -glupy_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_STAT]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_stat_t)(priv->fops[GLUPY_STAT]))(frame, this, loc, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_stat_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->stat, loc, xdata); -    return 0; -} - -void -wind_stat(call_frame_t *frame, xlator_t *xl, loc_t *loc, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_stat_cbk, xl, xl->fops->stat, loc, xdata); -} - -void -unwind_stat(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -            int32_t op_errno, struct iatt *buf, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, buf, xdata); -} - -void -set_stat_fop(long py_this, fop_stat_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_STAT] = (long)fop; -} - -void -set_stat_cbk(long py_this, fop_stat_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_STAT] = (long)cbk; -} - -/* FOP: FSTAT */ - -int32_t -glupy_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, struct iatt *buf, -                dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_FSTAT]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_fstat_cbk_t)(priv->cbks[GLUPY_FSTAT]))( -        frame, cookie, this, op_ret, op_errno, buf, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(fstat, frame, op_ret, op_errno, buf, xdata); -    return 0; -} - -int32_t -glupy_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_FSTAT]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_fstat_t)(priv->fops[GLUPY_FSTAT]))(frame, this, fd, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_fstat_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fstat, fd, xdata); -    return 0; -} - -void -wind_fstat(call_frame_t *frame, xlator_t *xl, fd_t *fd, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_fstat_cbk, xl, xl->fops->fstat, fd, xdata); -} - -void -unwind_fstat(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, struct iatt *buf, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(fstat, frame, op_ret, op_errno, buf, xdata); -} - -void -set_fstat_fop(long py_this, fop_fstat_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_FSTAT] = (long)fop; -} - -void -set_fstat_cbk(long py_this, fop_fstat_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_FSTAT] = (long)cbk; -} - -/* FOP:STATFS */ - -int32_t -glupy_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct statvfs *buf, -                 dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_STATFS]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_statfs_cbk_t)(priv->cbks[GLUPY_STATFS]))( -        frame, cookie, this, op_ret, op_errno, buf, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(statfs, frame, op_ret, op_errno, buf, xdata); -    return 0; -} - -int32_t -glupy_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_STATFS]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_statfs_t)(priv->fops[GLUPY_STATFS]))(frame, this, loc, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_statfs_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->statfs, loc, xdata); -    return 0; -} - -void -wind_statfs(call_frame_t *frame, xlator_t *xl, loc_t *loc, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_statfs_cbk, xl, xl->fops->statfs, loc, xdata); -} - -void -unwind_statfs(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct statvfs *buf, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(statfs, frame, op_ret, op_errno, buf, xdata); -} - -void -set_statfs_fop(long py_this, fop_statfs_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_STATFS] = (long)fop; -} - -void -set_statfs_cbk(long py_this, fop_statfs_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_STATFS] = (long)cbk; -} - -/* FOP: SETXATTR */ - -int32_t -glupy_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_SETXATTR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_setxattr_cbk_t)(priv->cbks[GLUPY_SETXATTR]))( -        frame, cookie, this, op_ret, op_errno, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int32_t -glupy_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, -               int32_t flags, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_SETXATTR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_setxattr_t)(priv->fops[GLUPY_SETXATTR]))(frame, this, loc, dict, -                                                         flags, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_setxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); -    return 0; -} - -void -wind_setxattr(call_frame_t *frame, xlator_t *xl, loc_t *loc, dict_t *dict, -              int32_t flags, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_setxattr_cbk, xl, xl->fops->setxattr, loc, dict, -               flags, xdata); -} - -void -unwind_setxattr(call_frame_t *frame, long cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); -} - -void -set_setxattr_fop(long py_this, fop_setxattr_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_SETXATTR] = (long)fop; -} - -void -set_setxattr_cbk(long py_this, fop_setxattr_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_SETXATTR] = (long)cbk; -} - -/* FOP: GETXATTR */ - -int32_t -glupy_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, dict_t *dict, -                   dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_GETXATTR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_getxattr_cbk_t)(priv->cbks[GLUPY_GETXATTR]))( -        frame, cookie, this, op_ret, op_errno, dict, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); -    return 0; -} - -int32_t -glupy_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, -               const char *name, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_GETXATTR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_getxattr_t)(priv->fops[GLUPY_GETXATTR]))(frame, this, loc, name, -                                                         xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_getxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); -    return 0; -} - -void -wind_getxattr(call_frame_t *frame, xlator_t *xl, loc_t *loc, const char *name, -              dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_getxattr_cbk, xl, xl->fops->getxattr, loc, name, -               xdata); -} - -void -unwind_getxattr(call_frame_t *frame, long cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); -} - -void -set_getxattr_fop(long py_this, fop_getxattr_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_GETXATTR] = (long)fop; -} - -void -set_getxattr_cbk(long py_this, fop_getxattr_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_GETXATTR] = (long)cbk; -} - -/* FOP: FSETXATTR */ - -int32_t -glupy_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_FSETXATTR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_fsetxattr_cbk_t)(priv->cbks[GLUPY_FSETXATTR]))( -        frame, cookie, this, op_ret, op_errno, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int32_t -glupy_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, -                int32_t flags, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_FSETXATTR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_fsetxattr_t)(priv->fops[GLUPY_FSETXATTR]))(frame, this, fd, -                                                           dict, flags, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_fsetxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); -    return 0; -} - -void -wind_fsetxattr(call_frame_t *frame, xlator_t *xl, fd_t *fd, dict_t *dict, -               int32_t flags, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_fsetxattr_cbk, xl, xl->fops->fsetxattr, fd, dict, -               flags, xdata); -} - -void -unwind_fsetxattr(call_frame_t *frame, long cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); -} - -void -set_fsetxattr_fop(long py_this, fop_fsetxattr_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_FSETXATTR] = (long)fop; -} - -void -set_fsetxattr_cbk(long py_this, fop_fsetxattr_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_FSETXATTR] = (long)cbk; -} - -/* FOP: FGETXATTR */ - -int32_t -glupy_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, dict_t *dict, -                    dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_FGETXATTR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_fgetxattr_cbk_t)(priv->cbks[GLUPY_FGETXATTR]))( -        frame, cookie, this, op_ret, op_errno, dict, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata); -    return 0; -} - -int32_t -glupy_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, -                dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_FGETXATTR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_fgetxattr_t)(priv->fops[GLUPY_FGETXATTR]))(frame, this, fd, -                                                           name, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_fgetxattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); -    return 0; -} - -void -wind_fgetxattr(call_frame_t *frame, xlator_t *xl, fd_t *fd, const char *name, -               dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_fgetxattr_cbk, xl, xl->fops->fgetxattr, fd, name, -               xdata); -} - -void -unwind_fgetxattr(call_frame_t *frame, long cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata); -} - -void -set_fgetxattr_fop(long py_this, fop_fgetxattr_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_FGETXATTR] = (long)fop; -} - -void -set_fgetxattr_cbk(long py_this, fop_fgetxattr_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_FGETXATTR] = (long)cbk; -} - -/* FOP:REMOVEXATTR */ - -int32_t -glupy_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                      int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_REMOVEXATTR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_removexattr_cbk_t)(priv->cbks[GLUPY_REMOVEXATTR]))( -        frame, cookie, this, op_ret, op_errno, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(removexattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int32_t -glupy_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, -                  const char *name, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_REMOVEXATTR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_removexattr_t)(priv->fops[GLUPY_REMOVEXATTR]))(frame, this, loc, -                                                               name, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_removexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); -    return 0; -} - -void -wind_removexattr(call_frame_t *frame, xlator_t *xl, loc_t *loc, -                 const char *name, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_removexattr_cbk, xl, xl->fops->removexattr, loc, -               name, xdata); -} - -void -unwind_removexattr(call_frame_t *frame, long cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(removexattr, frame, op_ret, op_errno, xdata); -} - -void -set_removexattr_fop(long py_this, fop_removexattr_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_REMOVEXATTR] = (long)fop; -} - -void -set_removexattr_cbk(long py_this, fop_removexattr_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_REMOVEXATTR] = (long)cbk; -} - -/* FOP:FREMOVEXATTR */ - -int32_t -glupy_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_FREMOVEXATTR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_fremovexattr_cbk_t)(priv->cbks[GLUPY_FREMOVEXATTR]))( -        frame, cookie, this, op_ret, op_errno, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(fremovexattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -int32_t -glupy_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, -                   const char *name, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_FREMOVEXATTR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_fremovexattr_t)(priv->fops[GLUPY_FREMOVEXATTR]))( -        frame, this, fd, name, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_fremovexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); -    return 0; -} - -void -wind_fremovexattr(call_frame_t *frame, xlator_t *xl, fd_t *fd, const char *name, -                  dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_fremovexattr_cbk, xl, xl->fops->fremovexattr, fd, -               name, xdata); -} - -void -unwind_fremovexattr(call_frame_t *frame, long cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(fremovexattr, frame, op_ret, op_errno, xdata); -} - -void -set_fremovexattr_fop(long py_this, fop_fremovexattr_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_FREMOVEXATTR] = (long)fop; -} - -void -set_fremovexattr_cbk(long py_this, fop_fremovexattr_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_FREMOVEXATTR] = (long)cbk; -} - -/* FOP: LINK*/ -int32_t -glupy_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, inode_t *inode, -               struct iatt *buf, struct iatt *preparent, -               struct iatt *postparent, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_LINK]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_link_cbk_t)(priv->cbks[GLUPY_LINK]))( -        frame, cookie, this, op_ret, op_errno, inode, buf, preparent, -        postparent, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(link, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -    return 0; -} - -int32_t -glupy_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -           dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_LINK]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_link_t)(priv->fops[GLUPY_LINK]))(frame, this, oldloc, newloc, -                                                 xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_link_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); -    return 0; -} - -void -wind_link(call_frame_t *frame, xlator_t *xl, loc_t *oldloc, loc_t *newloc, -          dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_link_cbk, xl, xl->fops->link, oldloc, newloc, -               xdata); -} - -void -unwind_link(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -            int32_t op_errno, inode_t *inode, struct iatt *buf, -            struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(link, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -} - -void -set_link_fop(long py_this, fop_link_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_LINK] = (long)fop; -} - -void -set_link_cbk(long py_this, fop_link_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_LINK] = (long)cbk; -} - -/* FOP: SYMLINK*/ -int32_t -glupy_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, inode_t *inode, -                  struct iatt *buf, struct iatt *preparent, -                  struct iatt *postparent, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_SYMLINK]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_symlink_cbk_t)(priv->cbks[GLUPY_SYMLINK]))( -        frame, cookie, this, op_ret, op_errno, inode, buf, preparent, -        postparent, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(symlink, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -    return 0; -} - -int32_t -glupy_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, -              loc_t *loc, mode_t umask, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_SYMLINK]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_symlink_t)(priv->fops[GLUPY_SYMLINK]))(frame, this, linkname, -                                                       loc, umask, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_symlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); -    return 0; -} - -void -wind_symlink(call_frame_t *frame, xlator_t *xl, const char *linkname, -             loc_t *loc, mode_t umask, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_symlink_cbk, xl, xl->fops->symlink, linkname, loc, -               umask, xdata); -} - -void -unwind_symlink(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -               int32_t op_errno, inode_t *inode, struct iatt *buf, -               struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(symlink, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -} - -void -set_symlink_fop(long py_this, fop_symlink_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_SYMLINK] = (long)fop; -} - -void -set_symlink_cbk(long py_this, fop_symlink_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_SYMLINK] = (long)cbk; -} - -/* FOP: READLINK */ -int32_t -glupy_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                   int32_t op_ret, int32_t op_errno, const char *path, -                   struct iatt *buf, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_READLINK]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_readlink_cbk_t)(priv->cbks[GLUPY_READLINK]))( -        frame, cookie, this, op_ret, op_errno, path, buf, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(readlink, frame, op_ret, op_errno, path, buf, xdata); -    return 0; -} - -int32_t -glupy_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, -               dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_READLINK]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_readlink_t)(priv->fops[GLUPY_READLINK]))(frame, this, loc, size, -                                                         xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_readlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readlink, loc, size, xdata); -    return 0; -} - -void -wind_readlink(call_frame_t *frame, xlator_t *xl, loc_t *loc, size_t size, -              dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_readlink_cbk, xl, xl->fops->readlink, loc, size, -               xdata); -} - -void -unwind_readlink(call_frame_t *frame, long cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, const char *path, -                struct iatt *buf, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(readlink, frame, op_ret, op_errno, path, buf, xdata); -} - -void -set_readlink_fop(long py_this, fop_readlink_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_READLINK] = (long)fop; -} - -void -set_readlink_cbk(long py_this, fop_readlink_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_READLINK] = (long)cbk; -} - -/* FOP: UNLINK */ - -int32_t -glupy_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                 int32_t op_ret, int32_t op_errno, struct iatt *preparent, -                 struct iatt *postparent, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_UNLINK]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_unlink_cbk_t)(priv->cbks[GLUPY_UNLINK]))( -        frame, cookie, this, op_ret, op_errno, preparent, postparent, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, -                        xdata); -    return 0; -} - -int32_t -glupy_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, -             dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_UNLINK]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_unlink_t)(priv->fops[GLUPY_UNLINK]))(frame, this, loc, xflags, -                                                     xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_unlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->unlink, loc, xflags, xdata); -    return 0; -} - -void -wind_unlink(call_frame_t *frame, xlator_t *xl, loc_t *loc, int xflags, -            dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_unlink_cbk, xl, xl->fops->unlink, loc, xflags, -               xdata); -} - -void -unwind_unlink(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -              int32_t op_errno, struct iatt *preparent, struct iatt *postparent, -              dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, -                        xdata); -} - -void -set_unlink_fop(long py_this, fop_unlink_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_UNLINK] = (long)fop; -} - -void -set_unlink_cbk(long py_this, fop_unlink_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_UNLINK] = (long)cbk; -} - -/* FOP: MKDIR */ - -int32_t -glupy_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, inode_t *inode, -                struct iatt *buf, struct iatt *preparent, -                struct iatt *postparent, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_MKDIR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_mkdir_cbk_t)(priv->cbks[GLUPY_MKDIR]))( -        frame, cookie, this, op_ret, op_errno, inode, buf, preparent, -        postparent, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -    return 0; -} - -int32_t -glupy_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, -            mode_t umask, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_MKDIR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_mkdir_t)(priv->fops[GLUPY_MKDIR]))(frame, this, loc, mode, -                                                   umask, xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_mkdir_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); -    return 0; -} - -void -wind_mkdir(call_frame_t *frame, xlator_t *xl, loc_t *loc, mode_t mode, -           mode_t umask, dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_mkdir_cbk, xl, xl->fops->mkdir, loc, mode, umask, -               xdata); -} - -void -unwind_mkdir(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, inode_t *inode, struct iatt *buf, -             struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -} - -void -set_mkdir_fop(long py_this, fop_mkdir_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_MKDIR] = (long)fop; -} - -void -set_mkdir_cbk(long py_this, fop_mkdir_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_MKDIR] = (long)cbk; -} - -/* FOP: RMDIR */ - -int32_t -glupy_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                int32_t op_ret, int32_t op_errno, struct iatt *preparent, -                struct iatt *postparent, dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; - -    if (!priv->cbks[GLUPY_RMDIR]) { -        goto unwind; -    } - -    gstate = glupy_enter(); -    ret = ((fop_rmdir_cbk_t)(priv->cbks[GLUPY_RMDIR]))( -        frame, cookie, this, op_ret, op_errno, preparent, postparent, xdata); -    glupy_leave(gstate); - -    return ret; - -unwind: -    frame->local = NULL; -    STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, preparent, postparent, -                        xdata); -    return 0; -} - -int32_t -glupy_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, -            dict_t *xdata) -{ -    glupy_private_t *priv = this->private; -    PyGILState_STATE gstate; -    int32_t ret; -    static long next_id = 0; - -    if (!priv->fops[GLUPY_RMDIR]) { -        goto wind; -    } - -    gstate = glupy_enter(); -    frame->local = (void *)++next_id; -    ret = ((fop_rmdir_t)(priv->fops[GLUPY_RMDIR]))(frame, this, loc, xflags, -                                                   xdata); -    glupy_leave(gstate); - -    return ret; - -wind: -    STACK_WIND(frame, glupy_rmdir_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->rmdir, loc, xflags, xdata); -    return 0; -} - -void -wind_rmdir(call_frame_t *frame, xlator_t *xl, loc_t *loc, int xflags, -           dict_t *xdata) -{ -    xlator_t *this = THIS; - -    if (!xl || (xl == this)) { -        xl = FIRST_CHILD(this); -    } - -    STACK_WIND(frame, glupy_rmdir_cbk, xl, xl->fops->rmdir, loc, xflags, xdata); -} - -void -unwind_rmdir(call_frame_t *frame, long cookie, xlator_t *this, int32_t op_ret, -             int32_t op_errno, struct iatt *preparent, struct iatt *postparent, -             dict_t *xdata) -{ -    frame->local = NULL; -    STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, preparent, postparent, -                        xdata); -} - -void -set_rmdir_fop(long py_this, fop_rmdir_t fop) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->fops[GLUPY_RMDIR] = (long)fop; -} - -void -set_rmdir_cbk(long py_this, fop_rmdir_cbk_t cbk) -{ -    glupy_private_t *priv = ((xlator_t *)py_this)->private; - -    priv->cbks[GLUPY_RMDIR] = (long)cbk; -} - -/* NON-FOP-SPECIFIC CODE */ - -long -get_id(call_frame_t *frame) -{ -    return (long)(frame->local); -} - -uint64_t -get_rootunique(call_frame_t *frame) -{ -    return frame->root->unique; -} - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    if (!this) -        return ret; - -    ret = xlator_mem_acct_init(this, gf_glupy_mt_end); - -    if (ret != 0) { -        gf_log(this->name, GF_LOG_ERROR, -               "Memory accounting init" -               " failed"); -        return ret; -    } - -    return ret; -} - -static void -py_error_log(const char *name, PyObject *pystr) -{ -#if PY_MAJOR_VERSION > 2 -    char scr[256]; -    if (PyUnicode_Check(pystr)) { -        PyObject *tmp = PyUnicode_AsEncodedString(pystr, "UTF-8", "strict"); -        if (tmp != NULL) { -            strncpy(scr, PyBytes_AS_STRING(pystr), sizeof(scr)); -            Py_DECREF(tmp); -        } else { -            strncpy(scr, "string encoding error", sizeof(scr)); -        } -    } else if (PyBytes_Check(pystr)) { -        strncpy(scr, PyBytes_AS_STRING(pystr), sizeof(scr)); -    } else { -        strncpy(scr, "string encoding error", sizeof(scr)); -    } -    gf_log(name, GF_LOG_ERROR, "Python error: %s", scr); -#else -    gf_log(name, GF_LOG_ERROR, "Python error: %s", PyString_AsString(pystr)); -#endif -} - -static PyObject * -encode(const char *str) -{ -#if PY_MAJOR_VERSION > 2 -    return PyUnicode_FromString(str); -#else -    return PyString_FromString(str); -#endif -} - -int32_t -init(xlator_t *this) -{ -    glupy_private_t *priv = NULL; -    char *module_name = NULL; -    PyObject *py_mod_name = NULL; -    PyObject *py_init_func = NULL; -    PyObject *py_args = NULL; -    PyObject *syspath = NULL; -    PyObject *path = NULL; -    PyObject *error_type = NULL; -    PyObject *error_msg = NULL; -    PyObject *error_bt = NULL; -    static gf_boolean_t py_inited = _gf_false; -    void *err_cleanup = &&err_return; -    char libpython[16]; - -    if (dict_get_str(this->options, "module-name", &module_name) != 0) { -        gf_log(this->name, GF_LOG_ERROR, "missing module-name"); -        return -1; -    } - -    priv = GF_CALLOC(1, sizeof(glupy_private_t), gf_glupy_mt_priv); -    if (!priv) { -        goto *err_cleanup; -    } -    this->private = priv; -    err_cleanup = &&err_free_priv; - -    if (!py_inited) { -        /* FIXME: -         * This hack is necessary because glusterfs (rightly) loads -         * glupy.so with RTLD_LOCAL but glupy needs libpython to be -         * loaded with RTLD_GLOBAL even though glupy is correctly -         * linked with libpython. -         * This is needed because one of the internal modules of -         * python 2.x (lib-dynload/_struct.so) does not explicitly -         * link with libpython. -         */ -        snprintf(libpython, sizeof(libpython), "libpython%d.%d.so", -                 PY_MAJOR_VERSION, PY_MINOR_VERSION); -        if (!dlopen(libpython, RTLD_NOW | RTLD_GLOBAL)) { -            gf_msg(this->name, GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, -                   "dlopen(%s) failed: %s", libpython, dlerror()); -        } - -        /* -         * This must be done before Py_Initialize(), -         * because it will duplicate the environment, -         * and fail to see later environment updates. -         */ -        setenv("PATH_GLUSTERFS_GLUPY_MODULE", PATH_GLUSTERFS_GLUPY_MODULE, 1); - -        Py_Initialize(); -        PyEval_InitThreads(); - -        (void)pthread_key_create(&gil_init_key, NULL); -        (void)pthread_setspecific(gil_init_key, (void *)1); - -        /* PyEval_InitThreads takes this "for" us.  No thanks. */ -        PyEval_ReleaseLock(); -        py_inited = _gf_true; -    } - -    /* Adjust python's path */ -    syspath = PySys_GetObject("path"); -    path = encode(GLUSTER_PYTHON_PATH); -    PyList_Append(syspath, path); -    Py_DECREF(path); - -    py_mod_name = encode(module_name); -    if (!py_mod_name) { -        gf_log(this->name, GF_LOG_ERROR, "could not create name"); -        if (PyErr_Occurred()) { -            PyErr_Fetch(&error_type, &error_msg, &error_bt); -            py_error_log(this->name, error_msg); -        } -        goto *err_cleanup; -    } - -    gf_log(this->name, GF_LOG_DEBUG, "py_mod_name = %s", module_name); -    priv->py_module = PyImport_Import(py_mod_name); -    Py_DECREF(py_mod_name); -    if (!priv->py_module) { -        gf_log(this->name, GF_LOG_ERROR, "Python import of %s failed", -               module_name); -        if (PyErr_Occurred()) { -            PyErr_Fetch(&error_type, &error_msg, &error_bt); -            py_error_log(this->name, error_msg); -        } -        goto *err_cleanup; -    } -    gf_log(this->name, GF_LOG_INFO, "Import of %s succeeded", module_name); -    err_cleanup = &&err_deref_module; - -    py_init_func = PyObject_GetAttrString(priv->py_module, "xlator"); -    if (!py_init_func || !PyCallable_Check(py_init_func)) { -        gf_log(this->name, GF_LOG_ERROR, "missing init func"); -        if (PyErr_Occurred()) { -            PyErr_Fetch(&error_type, &error_msg, &error_bt); -            py_error_log(this->name, error_msg); -        } -        goto *err_cleanup; -    } -    err_cleanup = &&err_deref_init; - -    py_args = PyTuple_New(1); -    if (!py_args) { -        gf_log(this->name, GF_LOG_ERROR, "could not create args"); -        if (PyErr_Occurred()) { -            PyErr_Fetch(&error_type, &error_msg, &error_bt); -            py_error_log(this->name, error_msg); -        } -        goto *err_cleanup; -    } -    PyTuple_SetItem(py_args, 0, PyLong_FromLong((long)this)); - -    /* TBD: pass in list of children */ -    priv->py_xlator = PyObject_CallObject(py_init_func, py_args); -    Py_DECREF(py_args); -    if (!priv->py_xlator) { -        gf_log(this->name, GF_LOG_ERROR, "Python init failed"); -        if (PyErr_Occurred()) { -            PyErr_Fetch(&error_type, &error_msg, &error_bt); -            py_error_log(this->name, error_msg); -        } -        goto *err_cleanup; -    } -    gf_log(this->name, GF_LOG_DEBUG, "init returned %p", priv->py_xlator); - -    return 0; - -err_deref_init: -    Py_DECREF(py_init_func); -err_deref_module: -    Py_DECREF(priv->py_module); -err_free_priv: -    GF_FREE(priv); -err_return: -    return -1; -} - -void -fini(xlator_t *this) -{ -    glupy_private_t *priv = this->private; - -    if (!priv) -        return; -    Py_DECREF(priv->py_xlator); -    Py_DECREF(priv->py_module); -    this->private = NULL; -    GF_FREE(priv); - -    return; -} - -struct xlator_fops fops = {.lookup = glupy_lookup, -                           .create = glupy_create, -                           .open = glupy_open, -                           .readv = glupy_readv, -                           .writev = glupy_writev, -                           .opendir = glupy_opendir, -                           .readdir = glupy_readdir, -                           .stat = glupy_stat, -                           .fstat = glupy_fstat, -                           .setxattr = glupy_setxattr, -                           .getxattr = glupy_getxattr, -                           .fsetxattr = glupy_fsetxattr, -                           .fgetxattr = glupy_fgetxattr, -                           .removexattr = glupy_removexattr, -                           .fremovexattr = glupy_fremovexattr, -                           .link = glupy_link, -                           .unlink = glupy_unlink, -                           .readlink = glupy_readlink, -                           .symlink = glupy_symlink, -                           .mkdir = glupy_mkdir, -                           .rmdir = glupy_rmdir, -                           .statfs = glupy_statfs, -                           .readdirp = glupy_readdirp}; - -struct xlator_cbks cbks = {}; - -struct volume_options options[] = { -    {.key = {NULL}}, -}; diff --git a/xlators/features/glupy/src/glupy.h b/xlators/features/glupy/src/glupy.h deleted file mode 100644 index ca3ac170451..00000000000 --- a/xlators/features/glupy/src/glupy.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -   Copyright (c) 2006-2014 Red Hat, Inc. <http://www.redhat.com> -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ - -#ifndef __GLUPY_H__ -#define __GLUPY_H__ - -#include <glusterfs/mem-types.h> - -enum { -    GLUPY_LOOKUP = 0, -    GLUPY_CREATE, -    GLUPY_OPEN, -    GLUPY_READV, -    GLUPY_WRITEV, -    GLUPY_OPENDIR, -    GLUPY_READDIR, -    GLUPY_READDIRP, -    GLUPY_STAT, -    GLUPY_FSTAT, -    GLUPY_STATFS, -    GLUPY_SETXATTR, -    GLUPY_GETXATTR, -    GLUPY_FSETXATTR, -    GLUPY_FGETXATTR, -    GLUPY_REMOVEXATTR, -    GLUPY_FREMOVEXATTR, -    GLUPY_LINK, -    GLUPY_UNLINK, -    GLUPY_READLINK, -    GLUPY_SYMLINK, -    GLUPY_MKNOD, -    GLUPY_MKDIR, -    GLUPY_RMDIR, -    GLUPY_N_FUNCS -}; - -typedef struct { -    PyObject *py_module; -    PyObject *py_xlator; -    long fops[GLUPY_N_FUNCS]; -    long cbks[GLUPY_N_FUNCS]; -} glupy_private_t; - -enum gf_glupy_mem_types_ { -    gf_glupy_mt_priv = gf_common_mt_end + 1, -    gf_glupy_mt_end -}; - -#endif /* __GLUPY_H__ */ diff --git a/xlators/features/glupy/src/glupy.sym b/xlators/features/glupy/src/glupy.sym deleted file mode 100644 index 55d9a300108..00000000000 --- a/xlators/features/glupy/src/glupy.sym +++ /dev/null @@ -1,101 +0,0 @@ -init -fini -fops -cbks -options -notify -mem_acct_init -reconfigure -dumpops -set_lookup_fop -set_lookup_cbk -set_create_fop -set_create_cbk -set_open_fop -set_open_cbk -set_readv_fop -set_readv_cbk -set_writev_fop -set_writev_cbk -set_opendir_fop -set_opendir_cbk -set_readdir_fop -set_readdir_cbk -set_readdirp_fop -set_readdirp_cbk -set_stat_fop -set_stat_cbk -set_fstat_fop -set_fstat_cbk -set_statfs_fop -set_statfs_cbk -set_setxattr_fop -set_setxattr_cbk -set_getxattr_fop -set_getxattr_cbk -set_fsetxattr_fop -set_fsetxattr_cbk -set_fgetxattr_fop -set_fgetxattr_cbk -set_removexattr_fop -set_removexattr_cbk -set_fremovexattr_fop -set_fremovexattr_cbk -set_link_fop -set_link_cbk -set_symlink_fop -set_symlink_cbk -set_readlink_fop -set_readlink_cbk -set_unlink_fop -set_unlink_cbk -set_mkdir_fop -set_mkdir_cbk -set_rmdir_fop -set_rmdir_cbk -wind_lookup -wind_create -wind_open -wind_readv -wind_writev -wind_opendir -wind_readdir -wind_readdirp -wind_stat -wind_fstat -wind_statfs -wind_setxattr -wind_getxattr -wind_fsetxattr -wind_fgetxattr -wind_removexattr -wind_fremovexattr -wind_link -wind_symlink -wind_readlink -wind_unlink -wind_mkdir -wind_rmdir -unwind_lookup -unwind_create -unwind_open -unwind_readv -unwind_writev -unwind_opendir -unwind_readdir -unwind_readdirp -unwind_stat -unwind_fstat -unwind_statfs -unwind_setxattr -unwind_getxattr -unwind_fsetxattr -unwind_fgetxattr -unwind_removexattr -unwind_fremovexattr -unwind_link -unwind_symlink -unwind_readlink -unwind_unlink -unwind_mkdir -unwind_rmdir diff --git a/xlators/features/glupy/src/glupy/Makefile.am b/xlators/features/glupy/src/glupy/Makefile.am deleted file mode 100644 index 573d2da12e1..00000000000 --- a/xlators/features/glupy/src/glupy/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -# Install __init__.py into the Python site-packages area -pyglupydir = @BUILD_PYTHON_SITE_PACKAGES@/gluster/glupy -pyglupy_PYTHON = __init__.py - -CLEANFILES = diff --git a/xlators/features/glupy/src/glupy/__init__.py b/xlators/features/glupy/src/glupy/__init__.py deleted file mode 100644 index 576fbdb9945..00000000000 --- a/xlators/features/glupy/src/glupy/__init__.py +++ /dev/null @@ -1,852 +0,0 @@ -## -## Copyright (c) 2006-2014 Red Hat, Inc. <http://www.redhat.com> -## This file is part of GlusterFS. -## -## This file is licensed to you under your choice of the GNU Lesser -## General Public License, version 3 or any later version (LGPLv3 or -## later), or the GNU General Public License, version 2 (GPLv2), in all -## cases as published by the Free Software Foundation. -## - -import sys -import os -from ctypes import * - -dl = CDLL(os.getenv("PATH_GLUSTERFS_GLUPY_MODULE", ""), RTLD_GLOBAL) - - -class call_frame_t (Structure): -        pass - -class dev_t (Structure): -        pass - - -class dict_t (Structure): -        pass - - -class gf_dirent_t (Structure): -        pass - - -class iobref_t (Structure): -	pass - - -class iovec_t (Structure): -        pass - - -class list_head (Structure): -        pass - -list_head._fields_ = [ -                ("next", POINTER(list_head)), -                ("prev", POINTER(list_head)) -        ] - - -class rwxperm_t (Structure): -        _fields_ = [ -                ("read", c_uint8, 1), -                ("write", c_uint8, 1), -                ("execn", c_uint8, 1) -        ] - - -class statvfs_t (Structure): -        pass - - -class xlator_t (Structure): -        pass - - -class ia_prot_t (Structure): -        _fields_ = [ -                ("suid", c_uint8, 1), -                ("sgid", c_uint8, 1), -                ("sticky", c_uint8, 1), -                ("owner", rwxperm_t), -                ("group", rwxperm_t), -                ("other", rwxperm_t) -        ] - -# For checking file type. -(IA_INVAL, IA_IFREG, IA_IFDIR, IA_IFLNK, IA_IFBLK, IA_IFCHR, IA_IFIFO, - IA_IFSOCK) = range(8) - - -class iatt_t (Structure): -        _fields_ = [ -                ("ia_no", c_uint64), -                ("ia_gfid", c_ubyte * 16), -                ("ia_dev", c_uint64), -                ("ia_type", c_uint), -                ("ia_prot", ia_prot_t), -                ("ia_nlink", c_uint32), -                ("ia_uid", c_uint32), -                ("ia_gid", c_uint32), -                ("ia_rdev", c_uint64), -                ("ia_size", c_uint64), -                ("ia_blksize", c_uint32), -                ("ia_blocks", c_uint64), -                ("ia_atime", c_uint32 ), -                ("ia_atime_nsec", c_uint32), -                ("ia_mtime", c_uint32), -                ("ia_mtime_nsec", c_uint32), -                ("ia_ctime", c_uint32), -                ("ia_ctime_nsec", c_uint32) -        ] - - -class mem_pool (Structure): -        _fields_ = [ -                ("list", list_head), -                ("hot_count", c_int), -                ("cold_count", c_int), -                ("lock", c_void_p), -                ("padded_sizeof_type", c_ulong), -                ("pool", c_void_p), -                ("pool_end", c_void_p), -                ("real_sizeof_type", c_int), -                ("alloc_count", c_uint64), -                ("pool_misses", c_uint64), -                ("max_alloc", c_int), -                ("curr_stdalloc", c_int), -                ("max_stdalloc", c_int), -                ("name", c_char_p), -                ("global_list", list_head) -        ] - - -class U_ctx_key_inode (Union): -        _fields_ = [ -                ("key", c_uint64), -                ("xl_key", POINTER(xlator_t)) -        ] - - -class U_ctx_value1 (Union): -        _fields_ = [ -                ("value1", c_uint64), -                ("ptr1", c_void_p) -        ] - - -class U_ctx_value2 (Union): -        _fields_ = [ -                ("value2", c_uint64), -                ("ptr2", c_void_p) -        ] - -class inode_ctx (Structure): -        _anonymous_ = ("u_key", "u_value1", "u_value2",) -        _fields_ = [ -                ("u_key", U_ctx_key_inode), -                ("u_value1", U_ctx_value1), -                ("u_value2", U_ctx_value2) -        ] - -class inode_t (Structure): -        pass - -class inode_table_t (Structure): -        _fields_ = [ -                ("lock", c_void_p), -                ("hashsize", c_size_t), -                ("name", c_char_p), -                ("root", POINTER(inode_t)), -                ("xl", POINTER(xlator_t)), -                ("lru_limit", c_uint32), -                ("inode_hash", POINTER(list_head)), -                ("name_hash", POINTER(list_head)), -                ("active", list_head), -                ("active_size", c_uint32), -                ("lru", list_head), -                ("lru_size", c_uint32), -                ("purge", list_head), -                ("purge_size", c_uint32), -                ("inode_pool", POINTER(mem_pool)), -                ("dentry_pool", POINTER(mem_pool)), -                ("fd_mem_pool", POINTER(mem_pool)) -        ] - -inode_t._fields_ = [ -                ("table", POINTER(inode_table_t)), -                ("gfid", c_ubyte * 16), -                ("lock", c_void_p), -                ("nlookup", c_uint64), -                ("fd_count", c_uint32), -                ("ref", c_uint32), -                ("ia_type", c_uint), -                ("fd_list", list_head), -                ("dentry_list", list_head), -                ("hashv", list_head), -                ("listv", list_head), -                ("ctx", POINTER(inode_ctx)) -        ] - - - -class U_ctx_key_fd (Union): -        _fields_ = [ -                ("key", c_uint64), -                ("xl_key", c_void_p) -        ] - -class fd_lk_ctx (Structure): -        _fields_ = [ -                ("lk_list", list_head), -                ("ref", c_int), -                ("lock", c_void_p) -        ] - -class fd_ctx (Structure): -        _anonymous_ = ("u_key", "u_value1") -        _fields_ = [ -                ("u_key", U_ctx_key_fd), -                ("u_value1", U_ctx_value1) -        ] - -class fd_t (Structure): -        _fields_ = [ -                ("pid", c_uint64), -                ("flags", c_int32), -                ("refcount", c_int32), -                ("inode_list", list_head), -                ("inode", POINTER(inode_t)), -                ("lock", c_void_p), -                ("ctx", POINTER(fd_ctx)), -                ("xl_count", c_int), -                ("lk_ctx", POINTER(fd_lk_ctx)), -                ("anonymous", c_uint) -        ] - -class loc_t (Structure): -        _fields_ = [ -                ("path", c_char_p), -                ("name", c_char_p), -                ("inode", POINTER(inode_t)), -                ("parent", POINTER(inode_t)), -                ("gfid", c_ubyte * 16), -                ("pargfid", c_ubyte * 16), -        ] - - - -def _init_op (a_class, fop, cbk, wind, unwind): -        # Decorators, used by translators. We could pass the signatures as -        # parameters, but it's actually kind of nice to keep them around for -        # inspection. -        a_class.fop_type = CFUNCTYPE(*a_class.fop_sig) -        a_class.cbk_type = CFUNCTYPE(*a_class.cbk_sig) -        # Dispatch-function registration. -        fop.restype = None -        fop.argtypes = [ c_long, a_class.fop_type ] -        # Callback-function registration. -        cbk.restype = None -        cbk.argtypes = [ c_long, a_class.cbk_type ] -        # STACK_WIND function. -        wind.restype = None -        wind.argtypes = list(a_class.fop_sig[1:]) -        # STACK_UNWIND function. -        unwind.restype = None -        unwind.argtypes = list(a_class.cbk_sig[1:]) - -class OpLookup: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(inode_t), POINTER(iatt_t), -                   POINTER(dict_t), POINTER(iatt_t)) -_init_op (OpLookup, dl.set_lookup_fop, dl.set_lookup_cbk, -                    dl.wind_lookup,    dl.unwind_lookup) - -class OpCreate: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_int, c_uint, c_uint, POINTER(fd_t), -                   POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(fd_t), POINTER(inode_t), -                   POINTER(iatt_t), POINTER(iatt_t), POINTER(iatt_t), -                   POINTER(dict_t)) -_init_op (OpCreate, dl.set_create_fop, dl.set_create_cbk, -                    dl.wind_create,    dl.unwind_create) - -class OpOpen: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_int, POINTER(fd_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(fd_t), POINTER(dict_t)) -_init_op (OpOpen, dl.set_open_fop, dl.set_open_cbk, -                  dl.wind_open,    dl.unwind_open) - -class OpReadv: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), c_size_t, c_long, c_uint32, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(iovec_t), c_int, POINTER(iatt_t), -                   POINTER(iobref_t), POINTER(dict_t)) -_init_op (OpReadv, dl.set_readv_fop, dl.set_readv_cbk, -                   dl.wind_readv,    dl.unwind_readv) -class OpWritev: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), POINTER(iovec_t), c_int, c_long, c_uint32, -                   POINTER(iobref_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(iatt_t), POINTER(iatt_t), -                   POINTER(dict_t)) -_init_op (OpWritev, dl.set_writev_fop, dl.set_writev_cbk, -                    dl.wind_writev,    dl.unwind_writev) - -class OpOpendir: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), POINTER(fd_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(fd_t), POINTER(dict_t)) -_init_op (OpOpendir, dl.set_opendir_fop, dl.set_opendir_cbk, -                     dl.wind_opendir,    dl.unwind_opendir) - -class OpReaddir: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), c_size_t, c_long, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(gf_dirent_t), POINTER(dict_t)) -_init_op (OpReaddir, dl.set_readdir_fop, dl.set_readdir_cbk, -                     dl.wind_readdir,    dl.unwind_readdir) - -class OpReaddirp: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), c_size_t, c_long, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(gf_dirent_t), POINTER(dict_t)) -_init_op (OpReaddirp, dl.set_readdirp_fop, dl.set_readdirp_cbk, -                      dl.wind_readdirp,    dl.unwind_readdirp) - -class OpStat: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(iatt_t), POINTER(dict_t)) -_init_op (OpStat, dl.set_stat_fop, dl.set_stat_cbk, -                  dl.wind_stat,    dl.unwind_stat) - -class OpFstat: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(iatt_t), POINTER(dict_t)) -_init_op (OpFstat, dl.set_fstat_fop, dl.set_fstat_cbk, -                   dl.wind_fstat,    dl.unwind_fstat) - -class OpStatfs: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(statvfs_t), POINTER(dict_t)) -_init_op (OpStatfs, dl.set_statfs_fop, dl.set_statfs_cbk, -                    dl.wind_statfs,    dl.unwind_statfs) - - -class OpSetxattr: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), POINTER(dict_t), c_int32, -                   POINTER (dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(dict_t)) -_init_op (OpSetxattr, dl.set_setxattr_fop, dl.set_setxattr_cbk, -                      dl.wind_setxattr,    dl.unwind_setxattr) - -class OpGetxattr: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_char_p, POINTER (dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(dict_t), POINTER(dict_t)) -_init_op (OpGetxattr, dl.set_getxattr_fop, dl.set_getxattr_cbk, -                      dl.wind_getxattr,    dl.unwind_getxattr) - -class OpFsetxattr: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), POINTER(dict_t), c_int32, -                   POINTER (dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(dict_t)) -_init_op (OpFsetxattr, dl.set_fsetxattr_fop, dl.set_fsetxattr_cbk, -                       dl.wind_fsetxattr,    dl.unwind_fsetxattr) - -class OpFgetxattr: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), c_char_p, POINTER (dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(dict_t), POINTER(dict_t)) -_init_op (OpFgetxattr, dl.set_fgetxattr_fop, dl.set_fgetxattr_cbk, -                       dl.wind_fgetxattr,    dl.unwind_fgetxattr) - -class OpRemovexattr: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_char_p, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(dict_t)) -_init_op (OpRemovexattr, dl.set_removexattr_fop, dl.set_removexattr_cbk, -                         dl.wind_removexattr,    dl.unwind_removexattr) - - -class OpFremovexattr: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(fd_t), c_char_p, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(dict_t)) -_init_op (OpFremovexattr, dl.set_fremovexattr_fop, dl.set_fremovexattr_cbk, -                          dl.wind_fremovexattr,    dl.unwind_fremovexattr) - -class OpLink: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), POINTER(loc_t), POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(inode_t), POINTER(iatt_t), -                   POINTER(iatt_t), POINTER(iatt_t), POINTER(dict_t)) -_init_op (OpLink, dl.set_link_fop, dl.set_link_cbk, -                  dl.wind_link,    dl.unwind_link) - -class OpSymlink: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   c_char_p, POINTER(loc_t), c_uint, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(inode_t), POINTER(iatt_t), -                   POINTER(iatt_t), POINTER(iatt_t), POINTER(dict_t)) -_init_op (OpSymlink, dl.set_symlink_fop, dl.set_symlink_cbk, -                     dl.wind_symlink,    dl.unwind_symlink) - -class OpUnlink: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_int, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(iatt_t), POINTER(iatt_t), -                   POINTER(dict_t)) -_init_op (OpUnlink, dl.set_unlink_fop, dl.set_unlink_cbk, -                    dl.wind_unlink,    dl.unwind_unlink) - -class OpReadlink: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_size_t, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, c_char_p, POINTER(iatt_t), POINTER(dict_t)) -_init_op (OpReadlink, dl.set_readlink_fop, dl.set_readlink_cbk, -                      dl.wind_readlink,    dl.unwind_readlink) - -class OpMkdir: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_uint, c_uint, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(inode_t), POINTER(iatt_t), -                   POINTER(iatt_t), POINTER(iatt_t), POINTER(dict_t)) -_init_op (OpMkdir, dl.set_mkdir_fop, dl.set_mkdir_cbk, -                   dl.wind_mkdir,    dl.unwind_mkdir) - -class OpRmdir: -        fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t), -                   POINTER(loc_t), c_int, POINTER(dict_t)) -        cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t), -                   c_int, c_int, POINTER(iatt_t), POINTER(iatt_t), -                   POINTER(dict_t)) -_init_op (OpRmdir, dl.set_rmdir_fop, dl.set_rmdir_cbk, -                   dl.wind_rmdir,    dl.unwind_rmdir) - - -class Translator: -        def __init__ (self, c_this): -                # This is only here to keep references to the stubs we create, -                # because ctypes doesn't and glupy.so can't because it doesn't -                # get a pointer to the actual Python object. It's a dictionary -                # instead of a list in case we ever allow changing fops/cbks -                # after initialization and need to look them up. -                self.stub_refs = {} -                funcs = dir(self.__class__) -                if "lookup_fop" in funcs: -                        @OpLookup.fop_type -                        def stub (frame, this, loc, xdata, s=self): -                                return s.lookup_fop (frame, this, loc, xdata) -                        self.stub_refs["lookup_fop"] = stub -                        dl.set_lookup_fop(c_this, stub) -                if "lookup_cbk" in funcs: -                        @OpLookup.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, inode, -                                  buf, xdata, postparent, s=self): -                                return s.lookup_cbk(frame, cookie, this, op_ret, -                                                    op_errno, inode, buf, xdata, -                                                    postparent) -                        self.stub_refs["lookup_cbk"] = stub -                        dl.set_lookup_cbk(c_this, stub) -                if "create_fop" in funcs: -                        @OpCreate.fop_type -                        def stub (frame, this, loc, flags, mode, umask, fd, -                                  xdata, s=self): -                                return s.create_fop (frame, this, loc, flags, -                                                     mode, umask, fd, xdata) -                        self.stub_refs["create_fop"] = stub -                        dl.set_create_fop(c_this, stub) -                if "create_cbk" in funcs: -                        @OpCreate.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, fd, -                                  inode, buf, preparent, postparent, xdata, -                                  s=self): -                                return s.create_cbk (frame, cookie, this, -                                                     op_ret, op_errno, fd, -                                                     inode, buf, preparent, -                                                     postparent, xdata) -                        self.stub_refs["create_cbk"] = stub -                        dl.set_create_cbk(c_this, stub) -                if "open_fop" in funcs: -                        @OpOpen.fop_type -                        def stub (frame, this, loc, flags, fd, -                                  xdata, s=self): -                                return s.open_fop (frame, this, loc, flags, -                                                   fd, xdata) -                        self.stub_refs["open_fop"] = stub -                        dl.set_open_fop(c_this, stub) -                if "open_cbk" in funcs: -                        @OpOpen.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, fd, -                                  xdata, s=self): -                                return s.open_cbk (frame, cookie, this, -                                                   op_ret, op_errno, fd, -                                                   xdata) -                        self.stub_refs["open_cbk"] = stub -                        dl.set_open_cbk(c_this, stub) -                if "readv_fop" in funcs: -                        @OpReadv.fop_type -                        def stub (frame, this, fd, size, offset, flags, -                                  xdata, s=self): -                                return s.readv_fop (frame, this, fd, size, -                                                    offset, flags, xdata) -                        self.stub_refs["readv_fop"] = stub -                        dl.set_readv_fop(c_this, stub) -                if "readv_cbk" in funcs: -                        @OpReadv.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  vector, count, stbuf, iobref, xdata, -                                  s=self): -                                return s.readv_cbk (frame, cookie, this, -                                                    op_ret, op_errno, vector, -                                                    count, stbuf, iobref, -                                                    xdata) -                        self.stub_refs["readv_cbk"] = stub -                        dl.set_readv_cbk(c_this, stub) -                if "writev_fop" in funcs: -                        @OpWritev.fop_type -                        def stub (frame, this, fd, vector, count, -                                  offset, flags, iobref, xdata, s=self): -                                return s.writev_fop (frame, this, fd, vector, -                                                     count, offset, flags, -                                                     iobref, xdata) -                        self.stub_refs["writev_fop"] = stub -                        dl.set_writev_fop(c_this, stub) -                if "writev_cbk" in funcs: -                        @OpWritev.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  prebuf, postbuf, xdata, s=self): -                                return s.writev_cbk (frame, cookie, this, -                                                     op_ret, op_errno, prebuf, -                                                     postbuf, xdata) -                        self.stub_refs["writev_cbk"] = stub -                        dl.set_writev_cbk(c_this, stub) -                if "opendir_fop" in funcs: -                        @OpOpendir.fop_type -                        def stub (frame, this, loc, fd, xdata, s=self): -                                return s.opendir_fop (frame, this, loc, fd, -                                                      xdata) -                        self.stub_refs["opendir_fop"] = stub -                        dl.set_opendir_fop(c_this, stub) -                if "opendir_cbk" in funcs: -                        @OpOpendir.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, fd, -                                  xdata, s=self): -                                return s.opendir_cbk(frame, cookie, this, -                                                     op_ret, op_errno, fd, -                                                     xdata) -                        self.stub_refs["opendir_cbk"] = stub -                        dl.set_opendir_cbk(c_this, stub) -                if "readdir_fop" in funcs: -                        @OpReaddir.fop_type -                        def stub (frame, this, fd, size, offset, xdata, s=self): -                                return s.readdir_fop (frame, this, fd, size, -                                                      offset, xdata) -                        self.stub_refs["readdir_fop"] = stub -                        dl.set_readdir_fop(c_this, stub) -                if "readdir_cbk" in funcs: -                        @OpReaddir.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  entries, xdata, s=self): -                                return s.readdir_cbk(frame, cookie, this, -                                                     op_ret, op_errno, entries, -                                                     xdata) -                        self.stub_refs["readdir_cbk"] = stub -                        dl.set_readdir_cbk(c_this, stub) -                if "readdirp_fop" in funcs: -                        @OpReaddirp.fop_type -                        def stub (frame, this, fd, size, offset, xdata, s=self): -                                return s.readdirp_fop (frame, this, fd, size, -                                                       offset, xdata) -                        self.stub_refs["readdirp_fop"] = stub -                        dl.set_readdirp_fop(c_this, stub) -                if "readdirp_cbk" in funcs: -                        @OpReaddirp.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  entries, xdata, s=self): -                                return s.readdirp_cbk (frame, cookie, this, -                                                       op_ret, op_errno, -                                                       entries, xdata) -                        self.stub_refs["readdirp_cbk"] = stub -                        dl.set_readdirp_cbk(c_this, stub) -                if "stat_fop" in funcs: -                        @OpStat.fop_type -                        def stub (frame, this, loc, xdata, s=self): -                                return s.stat_fop (frame, this, loc, xdata) -                        self.stub_refs["stat_fop"] = stub -                        dl.set_stat_fop(c_this, stub) -                if "stat_cbk" in funcs: -                        @OpStat.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, buf, -                                  xdata, s=self): -                                return s.stat_cbk(frame, cookie, this, op_ret, -                                                  op_errno, buf, xdata) -                        self.stub_refs["stat_cbk"] = stub -                        dl.set_stat_cbk(c_this, stub) -                if "fstat_fop" in funcs: -                        @OpFstat.fop_type -                        def stub (frame, this, fd, xdata, s=self): -                                return s.fstat_fop (frame, this, fd, xdata) -                        self.stub_refs["fstat_fop"] = stub -                        dl.set_fstat_fop(c_this, stub) -                if "fstat_cbk" in funcs: -                        @OpFstat.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, buf, -                                  xdata, s=self): -                                return s.fstat_cbk(frame, cookie, this, op_ret, -                                                   op_errno, buf, xdata) -                        self.stub_refs["fstat_cbk"] = stub -                        dl.set_fstat_cbk(c_this, stub) -                if "statfs_fop" in funcs: -                        @OpStatfs.fop_type -                        def stub (frame, this, loc, xdata, s=self): -                                return s.statfs_fop (frame, this, loc, xdata) -                        self.stub_refs["statfs_fop"] = stub -                        dl.set_statfs_fop(c_this, stub) -                if "statfs_cbk" in funcs: -                        @OpStatfs.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, buf, -                                  xdata, s=self): -                                return s.statfs_cbk (frame, cookie, this, -                                                     op_ret, op_errno, buf, -                                                     xdata) -                        self.stub_refs["statfs_cbk"] = stub -                        dl.set_statfs_cbk(c_this, stub) -                if "setxattr_fop" in funcs: -                        @OpSetxattr.fop_type -                        def stub (frame, this, loc, dictionary, flags, xdata, -                                  s=self): -                                return s.setxattr_fop (frame, this, loc, -                                                       dictionary, flags, -                                                       xdata) -                        self.stub_refs["setxattr_fop"] = stub -                        dl.set_setxattr_fop(c_this, stub) -                if "setxattr_cbk" in funcs: -                        @OpSetxattr.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, xdata, -                                  s=self): -                                return s.setxattr_cbk(frame, cookie, this, -                                                      op_ret, op_errno, xdata) -                        self.stub_refs["setxattr_cbk"] = stub -                        dl.set_setxattr_cbk(c_this, stub) -                if "getxattr_fop" in funcs: -                        @OpGetxattr.fop_type -                        def stub (frame, this, loc, name, xdata, s=self): -                                return s.getxattr_fop (frame, this, loc, name, -                                                       xdata) -                        self.stub_refs["getxattr_fop"] = stub -                        dl.set_getxattr_fop(c_this, stub) -                if "getxattr_cbk" in funcs: -                        @OpGetxattr.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  dictionary, xdata, s=self): -                                return s.getxattr_cbk(frame, cookie, this, -                                                      op_ret, op_errno, -                                                      dictionary, xdata) -                        self.stub_refs["getxattr_cbk"] = stub -                        dl.set_getxattr_cbk(c_this, stub) -                if "fsetxattr_fop" in funcs: -                        @OpFsetxattr.fop_type -                        def stub (frame, this, fd, dictionary, flags, xdata, -                                  s=self): -                                return s.fsetxattr_fop (frame, this, fd, -                                                        dictionary, flags, -                                                        xdata) -                        self.stub_refs["fsetxattr_fop"] = stub -                        dl.set_fsetxattr_fop(c_this, stub) -                if "fsetxattr_cbk" in funcs: -                        @OpFsetxattr.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, xdata, -                                  s=self): -                                return s.fsetxattr_cbk(frame, cookie, this, -                                                       op_ret, op_errno, xdata) -                        self.stub_refs["fsetxattr_cbk"] = stub -                        dl.set_fsetxattr_cbk(c_this, stub) -                if "fgetxattr_fop" in funcs: -                        @OpFgetxattr.fop_type -                        def stub (frame, this, fd, name, xdata, s=self): -                                return s.fgetxattr_fop (frame, this, fd, name, -                                                        xdata) -                        self.stub_refs["fgetxattr_fop"] = stub -                        dl.set_fgetxattr_fop(c_this, stub) -                if "fgetxattr_cbk" in funcs: -                        @OpFgetxattr.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  dictionary, xdata, s=self): -                                return s.fgetxattr_cbk(frame, cookie, this, -                                                       op_ret, op_errno, -                                                       dictionary, xdata) -                        self.stub_refs["fgetxattr_cbk"] = stub -                        dl.set_fgetxattr_cbk(c_this, stub) -                if "removexattr_fop" in funcs: -                        @OpRemovexattr.fop_type -                        def stub (frame, this, loc, name, xdata, s=self): -                                return s.removexattr_fop (frame, this, loc, -                                                          name, xdata) -                        self.stub_refs["removexattr_fop"] = stub -                        dl.set_removexattr_fop(c_this, stub) -                if "removexattr_cbk" in funcs: -                        @OpRemovexattr.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  xdata, s=self): -                                return s.removexattr_cbk(frame, cookie, this, -                                                         op_ret, op_errno, -                                                         xdata) -                        self.stub_refs["removexattr_cbk"] = stub -                        dl.set_removexattr_cbk(c_this, stub) -                if "fremovexattr_fop" in funcs: -                        @OpFremovexattr.fop_type -                        def stub (frame, this, fd, name, xdata, s=self): -                                return s.fremovexattr_fop (frame, this, fd, -                                                           name, xdata) -                        self.stub_refs["fremovexattr_fop"] = stub -                        dl.set_fremovexattr_fop(c_this, stub) -                if "fremovexattr_cbk" in funcs: -                        @OpFremovexattr.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  xdata, s=self): -                                return s.fremovexattr_cbk(frame, cookie, this, -                                                          op_ret, op_errno, -                                                          xdata) -                        self.stub_refs["fremovexattr_cbk"] = stub -                        dl.set_fremovexattr_cbk(c_this, stub) -                if "link_fop" in funcs: -                        @OpLink.fop_type -                        def stub (frame, this, oldloc, newloc, -                                  xdata, s=self): -                                return s.link_fop (frame, this, oldloc, -                                                   newloc, xdata) -                        self.stub_refs["link_fop"] = stub -                        dl.set_link_fop(c_this, stub) -                if "link_cbk" in funcs: -                        @OpLink.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  inode, buf, preparent, postparent, xdata, -                                  s=self): -                                return s.link_cbk (frame, cookie, this, -                                                   op_ret, op_errno, inode, -                                                   buf, preparent, -                                                   postparent, xdata) -                        self.stub_refs["link_cbk"] = stub -                        dl.set_link_cbk(c_this, stub) -                if "symlink_fop" in funcs: -                        @OpSymlink.fop_type -                        def stub (frame, this, linkname, loc, -                                  umask, xdata, s=self): -                                return s.symlink_fop (frame, this, linkname, -                                                      loc, umask, xdata) -                        self.stub_refs["symlink_fop"] = stub -                        dl.set_symlink_fop(c_this, stub) -                if "symlink_cbk" in funcs: -                        @OpSymlink.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  inode, buf, preparent, postparent, xdata, -                                  s=self): -                                return s.symlink_cbk (frame, cookie, this, -                                                      op_ret, op_errno, inode, -                                                      buf, preparent, -                                                      postparent, xdata) -                        self.stub_refs["symlink_cbk"] = stub -                        dl.set_symlink_cbk(c_this, stub) -                if "unlink_fop" in funcs: -                        @OpUnlink.fop_type -                        def stub (frame, this, loc, xflags, -                                  xdata, s=self): -                                return s.unlink_fop (frame, this, loc, -                                                     xflags, xdata) -                        self.stub_refs["unlink_fop"] = stub -                        dl.set_unlink_fop(c_this, stub) -                if "unlink_cbk" in funcs: -                        @OpUnlink.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  preparent, postparent, xdata, s=self): -                                return s.unlink_cbk (frame, cookie, this, -                                                     op_ret, op_errno, -                                                     preparent, postparent, -                                                     xdata) -                        self.stub_refs["unlink_cbk"] = stub -                        dl.set_unlink_cbk(c_this, stub) -                if "readlink_fop" in funcs: -                        @OpReadlink.fop_type -                        def stub (frame, this, loc, size, -                                  xdata, s=self): -                                return s.readlink_fop (frame, this, loc, -                                                       size, xdata) -                        self.stub_refs["readlink_fop"] = stub -                        dl.set_readlink_fop(c_this, stub) -                if "readlink_cbk" in funcs: -                        @OpReadlink.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  path, buf, xdata, s=self): -                                return s.readlink_cbk (frame, cookie, this, -                                                       op_ret, op_errno, -                                                       path, buf, xdata) -                        self.stub_refs["readlink_cbk"] = stub -                        dl.set_readlink_cbk(c_this, stub) -                if "mkdir_fop" in funcs: -                        @OpMkdir.fop_type -                        def stub (frame, this, loc, mode, umask, xdata, -                                  s=self): -                                return s.mkdir_fop (frame, this, loc, mode, -                                                    umask, xdata) -                        self.stub_refs["mkdir_fop"] = stub -                        dl.set_mkdir_fop(c_this, stub) -                if "mkdir_cbk" in funcs: -                        @OpMkdir.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, inode, -                                  buf, preparent, postparent, xdata, s=self): -                                return s.mkdir_cbk (frame, cookie, this, -                                                    op_ret, op_errno, inode, -                                                    buf, preparent, -                                                    postparent, xdata) -                        self.stub_refs["mkdir_cbk"] = stub -                        dl.set_mkdir_cbk(c_this, stub) -                if "rmdir_fop" in funcs: -                        @OpRmdir.fop_type -                        def stub (frame, this, loc, xflags, -                                  xdata, s=self): -                                return s.rmdir_fop (frame, this, loc, -                                                    xflags, xdata) -                        self.stub_refs["rmdir_fop"] = stub -                        dl.set_rmdir_fop(c_this, stub) -                if "rmdir_cbk" in funcs: -                        @OpRmdir.cbk_type -                        def stub (frame, cookie, this, op_ret, op_errno, -                                  preparent, postparent, xdata, s=self): -                                return s.rmdir_cbk (frame, cookie, this, -                                                    op_ret, op_errno, -                                                    preparent, postparent, -                                                    xdata) -                        self.stub_refs["rmdir_cbk"] = stub -                        dl.set_rmdir_cbk(c_this, stub) diff --git a/xlators/features/glupy/src/setup.py.in b/xlators/features/glupy/src/setup.py.in deleted file mode 100644 index 611e9695f76..00000000000 --- a/xlators/features/glupy/src/setup.py.in +++ /dev/null @@ -1,24 +0,0 @@ -from distutils.core import setup - -DESC = """GlusterFS is a distributed file-system capable of scaling to -several petabytes. It aggregates various storage bricks over Infiniband -RDMA or TCP/IP interconnect into one large parallel network file system. -GlusterFS is one of the most sophisticated file systems in terms of -features and extensibility.  It borrows a powerful concept called -Translators from GNU Hurd kernel. Much of the code in GlusterFS is in -user space and easily manageable. - -This package contains Glupy, the Python translator interface for GlusterFS.""" - -setup( -    name='glusterfs-glupy', -    version='@PACKAGE_VERSION@', -    description='Glupy is the Python translator interface for GlusterFS', -    long_description=DESC, -    author='Gluster Community', -    author_email='gluster-devel@gluster.org', -    license='LGPLv3', -    url='http://gluster.org/', -    package_dir={'gluster':''}, -    packages=['gluster'] -) diff --git a/xlators/performance/symlink-cache/Makefile.am b/xlators/performance/symlink-cache/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/xlators/performance/symlink-cache/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/xlators/performance/symlink-cache/src/Makefile.am b/xlators/performance/symlink-cache/src/Makefile.am deleted file mode 100644 index 0bfb03a68de..00000000000 --- a/xlators/performance/symlink-cache/src/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -xlator_LTLIBRARIES = symlink-cache.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/performance - -symlink_cache_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) - -symlink_cache_la_SOURCES = symlink-cache.c -symlink_cache_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -noinst_HEADERS = symlink-cache-messages.h - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src - -AM_CFLAGS = -Wall $(GF_CFLAGS) - -CLEANFILES =  diff --git a/xlators/performance/symlink-cache/src/symlink-cache-messages.h b/xlators/performance/symlink-cache/src/symlink-cache-messages.h deleted file mode 100644 index 40ff2e4b60b..00000000000 --- a/xlators/performance/symlink-cache/src/symlink-cache-messages.h +++ /dev/null @@ -1,30 +0,0 @@ -/*Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _SYMLINK_CACHE_MESSAGES_H_ -#define _SYMLINK_CACHE_MESSAGES_H_ - -#include <glusterfs/glfs-message-id.h> - -/* To add new message IDs, append new identifiers at the end of the list. - * - * Never remove a message ID. If it's not used anymore, you can rename it or - * leave it as it is, but not delete it. This is to prevent reutilization of - * IDs by other messages. - * - * The component name must match one of the entries defined in - * glfs-message-id.h. - */ - -GLFS_MSGID(SYMLINK_CACHE, SYMLINK_CACHE_MSG_XLATOR_CHILD_MISCONFIGURED, -           SYMLINK_CACHE_MSG_VOL_MISCONFIGURED, SYMLINK_CACHE_MSG_NO_MEMORY, -           SYMLINK_CACHE_MSG_DICT_GET_FAILED, -           SYMLINK_CACHE_MSG_DICT_SET_FAILED); - -#endif /* _SYMLINK_CACHE_MESSAGES_H_ */ diff --git a/xlators/performance/symlink-cache/src/symlink-cache.c b/xlators/performance/symlink-cache/src/symlink-cache.c deleted file mode 100644 index 07c3623ee94..00000000000 --- a/xlators/performance/symlink-cache/src/symlink-cache.c +++ /dev/null @@ -1,368 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <glusterfs/glusterfs.h> -#include <glusterfs/logging.h> -#include <glusterfs/dict.h> -#include <glusterfs/xlator.h> -#include <glusterfs/list.h> -#include <glusterfs/compat.h> -#include <glusterfs/compat-errno.h> -#include <glusterfs/common-utils.h> -#include "symlink-cache-messages.h" - -struct symlink_cache { -    time_t ctime; -    char *readlink; -}; - -static int -symlink_inode_ctx_get(inode_t *inode, xlator_t *this, void **ctx) -{ -    int ret = 0; -    uint64_t tmp_ctx = 0; -    ret = inode_ctx_get(inode, this, &tmp_ctx); -    if (-1 == ret) -        gf_msg(this->name, GF_LOG_ERROR, EINVAL, -               SYMLINK_CACHE_MSG_DICT_GET_FAILED, "dict get failed"); -    else -        *ctx = (void *)(long)tmp_ctx; - -    return 0; -} - -static int -symlink_inode_ctx_set(inode_t *inode, xlator_t *this, void *ctx) -{ -    int ret = 0; -    ret = inode_ctx_put(inode, this, (uint64_t)(long)ctx); -    if (-1 == ret) -        gf_msg(this->name, GF_LOG_ERROR, EINVAL, -               SYMLINK_CACHE_MSG_DICT_SET_FAILED, "dict set failed"); - -    return 0; -} - -int -sc_cache_update(xlator_t *this, inode_t *inode, const char *link) -{ -    struct symlink_cache *sc = NULL; - -    symlink_inode_ctx_get(inode, this, VOID(&sc)); -    if (!sc) -        return 0; - -    if (!sc->readlink) { -        gf_msg_debug(this->name, 0, "updating cache: %s", link); - -        sc->readlink = strdup(link); -    } else -        gf_msg_debug(this->name, 0, "not updating existing cache: %s with %s", -                     sc->readlink, link); - -    return 0; -} - -int -sc_cache_set(xlator_t *this, inode_t *inode, struct iatt *buf, const char *link) -{ -    struct symlink_cache *sc = NULL; -    int ret = -1; -    int need_set = 0; - -    symlink_inode_ctx_get(inode, this, VOID(&sc)); -    if (!sc) { -        need_set = 1; -        sc = CALLOC(1, sizeof(*sc)); -        if (!sc) { -            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, -                   SYMLINK_CACHE_MSG_NO_MEMORY, "out of memory :("); -            goto err; -        } -    } - -    if (sc->readlink) { -        gf_msg_debug(this->name, 0, -                     "replacing old cache: %s with new cache: %s", sc->readlink, -                     link); -        FREE(sc->readlink); -        sc->readlink = NULL; -    } - -    if (link) { -        sc->readlink = strdup(link); -        if (!sc->readlink) { -            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, -                   SYMLINK_CACHE_MSG_NO_MEMORY, "out of memory :("); -            goto err; -        } -    } - -    sc->ctime = buf->ia_ctime; - -    gf_msg_debug(this->name, 0, "setting symlink cache: %s", link); - -    if (need_set) { -        ret = symlink_inode_ctx_set(inode, this, sc); - -        if (ret < 0) { -            gf_msg(this->name, GF_LOG_ERROR, -ret, SYMLINK_CACHE_MSG_NO_MEMORY, -                   "could not set inode context "); -            goto err; -        } -    } - -    return 0; -err: - -    if (sc) { -        FREE(sc->readlink); -        sc->readlink = NULL; -        FREE(sc); -    } - -    return -1; -} - -int -sc_cache_flush(xlator_t *this, inode_t *inode) -{ -    struct symlink_cache *sc = NULL; - -    symlink_inode_ctx_get(inode, this, VOID(&sc)); -    if (!sc) -        return 0; - -    if (sc->readlink) { -        gf_msg_debug(this->name, 0, "flushing cache: %s", sc->readlink); - -        FREE(sc->readlink); -        sc->readlink = NULL; -    } - -    FREE(sc); - -    return 0; -} - -int -sc_cache_validate(xlator_t *this, inode_t *inode, struct iatt *buf) -{ -    struct symlink_cache *sc = NULL; -    uint64_t tmp_sc = 0; - -    if (!IA_ISLNK(buf->ia_type)) { -        sc_cache_flush(this, inode); -        return 0; -    } - -    symlink_inode_ctx_get(inode, this, VOID(&sc)); - -    if (!sc) { -        sc_cache_set(this, inode, buf, NULL); -        inode_ctx_get(inode, this, &tmp_sc); - -        if (!tmp_sc) { -            gf_msg(this->name, GF_LOG_ERROR, 0, SYMLINK_CACHE_MSG_NO_MEMORY, -                   "out of memory :("); -            return 0; -        } -        sc = (struct symlink_cache *)(long)tmp_sc; -    } - -    if (sc->ctime == buf->ia_ctime) -        return 0; - -    /* STALE */ -    if (sc->readlink) { -        gf_msg_debug(this->name, 0, "flushing cache: %s", sc->readlink); - -        FREE(sc->readlink); -        sc->readlink = NULL; -    } - -    sc->ctime = buf->ia_ctime; - -    return 0; -} - -int -sc_cache_get(xlator_t *this, inode_t *inode, char **link) -{ -    struct symlink_cache *sc = NULL; - -    symlink_inode_ctx_get(inode, this, VOID(&sc)); - -    if (!sc) -        return 0; - -    if (link && sc->readlink) -        *link = strdup(sc->readlink); -    return 0; -} - -int -sc_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                int op_errno, const char *link, struct iatt *sbuf, -                dict_t *xdata) -{ -    if (op_ret > 0) -        sc_cache_update(this, frame->local, link); - -    inode_unref(frame->local); -    frame->local = NULL; - -    STACK_UNWIND_STRICT(readlink, frame, op_ret, op_errno, link, sbuf, xdata); -    return 0; -} - -int -sc_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, -            dict_t *xdata) -{ -    char *link = NULL; -    int op_ret = -1; -    struct iatt buf = { -        0, -    }; - -    sc_cache_get(this, loc->inode, &link); - -    if (link) { -        /* cache hit */ -        gf_msg_debug(this->name, 0, "cache hit %s -> %s", loc->path, link); - -        /* -          libglusterfsclient, nfs or any other translators -          using buf in readlink_cbk should be aware that @buf -          is 0 filled -        */ -        op_ret = strlen(link); -        STACK_UNWIND_STRICT(readlink, frame, op_ret, 0, link, &buf, NULL); -        FREE(link); -        return 0; -    } - -    frame->local = inode_ref(loc->inode); - -    STACK_WIND(frame, sc_readlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readlink, loc, size, xdata); - -    return 0; -} - -int -sc_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -               int op_errno, inode_t *inode, struct iatt *buf, -               struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    if (op_ret == 0) { -        if (frame->local) { -            sc_cache_set(this, inode, buf, frame->local); -        } -    } - -    STACK_UNWIND_STRICT(symlink, frame, op_ret, op_errno, inode, buf, preparent, -                        postparent, xdata); -    return 0; -} - -int -sc_symlink(call_frame_t *frame, xlator_t *this, const char *dst, loc_t *src, -           mode_t umask, dict_t *xdata) -{ -    frame->local = strdup(dst); - -    STACK_WIND(frame, sc_symlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->symlink, dst, src, umask, xdata); - -    return 0; -} - -int -sc_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -              int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, -              struct iatt *postparent) -{ -    if (op_ret == 0) -        sc_cache_validate(this, inode, buf); -    else -        sc_cache_flush(this, inode); - -    STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, -                        postparent); -    return 0; -} - -int -sc_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    STACK_WIND(frame, sc_lookup_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lookup, loc, xdata); - -    return 0; -} - -int -sc_forget(xlator_t *this, inode_t *inode) -{ -    sc_cache_flush(this, inode); - -    return 0; -} - -int32_t -init(xlator_t *this) -{ -    if (!this->children || this->children->next) { -        gf_msg(this->name, GF_LOG_ERROR, 0, -               SYMLINK_CACHE_MSG_XLATOR_CHILD_MISCONFIGURED, -               "FATAL: volume (%s) not configured with exactly one " -               "child", -               this->name); -        return -1; -    } - -    if (!this->parents) { -        gf_msg(this->name, GF_LOG_WARNING, 0, -               SYMLINK_CACHE_MSG_VOL_MISCONFIGURED, -               "dangling volume. check volfile "); -    } - -    return 0; -} - -void -fini(xlator_t *this) -{ -    return; -} - -struct xlator_fops fops = { -    .lookup = sc_lookup, -    .symlink = sc_symlink, -    .readlink = sc_readlink, -}; - -struct xlator_cbks cbks = { -    .forget = sc_forget, -}; - -struct volume_options options[] = { -    { -        .key = {"symlink-cache"}, -        .type = GF_OPTION_TYPE_BOOL, -        .default_value = "off", -        .description = "enable/disable symlink-cache", -        .op_version = {GD_OP_VERSION_6_0}, -        .flags = OPT_FLAG_SETTABLE, -    }, -    {.key = {NULL}}, -}; diff --git a/xlators/cluster/stripe/Makefile.am b/xlators/playground/rot-13/Makefile.am index d471a3f9243..d471a3f9243 100644 --- a/xlators/cluster/stripe/Makefile.am +++ b/xlators/playground/rot-13/Makefile.am diff --git a/xlators/encryption/rot-13/src/Makefile.am b/xlators/playground/rot-13/src/Makefile.am index 9978661509d..9978661509d 100644 --- a/xlators/encryption/rot-13/src/Makefile.am +++ b/xlators/playground/rot-13/src/Makefile.am diff --git a/xlators/encryption/rot-13/src/rot-13.c b/xlators/playground/rot-13/src/rot-13.c index 0f45ee31964..0f45ee31964 100644 --- a/xlators/encryption/rot-13/src/rot-13.c +++ b/xlators/playground/rot-13/src/rot-13.c diff --git a/xlators/encryption/rot-13/src/rot-13.h b/xlators/playground/rot-13/src/rot-13.h index edbc99798b4..edbc99798b4 100644 --- a/xlators/encryption/rot-13/src/rot-13.h +++ b/xlators/playground/rot-13/src/rot-13.h diff --git a/xlators/storage/bd/Makefile.am b/xlators/storage/bd/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/storage/bd/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/storage/bd/src/Makefile.am b/xlators/storage/bd/src/Makefile.am deleted file mode 100644 index d56b42a1cbb..00000000000 --- a/xlators/storage/bd/src/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -if ENABLE_BD_XLATOR -xlator_LTLIBRARIES = bd.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/storage - -bd_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -LIBBD = -llvm2app -lrt -bd_la_SOURCES = bd.c bd-helper.c bd-aio.c -bd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ -	$(LIBBD) $(LIBAIO) - -noinst_HEADERS = bd.h bd-aio.h bd-mem-types.h - -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -	-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -	-I$(top_srcdir)/rpc/rpc-lib/src - -AM_CFLAGS = -fno-strict-aliasing -Wall $(GF_CFLAGS) - -CLEANFILES = - -endif diff --git a/xlators/storage/bd/src/bd-aio.c b/xlators/storage/bd/src/bd-aio.c deleted file mode 100644 index db73dc8978c..00000000000 --- a/xlators/storage/bd/src/bd-aio.c +++ /dev/null @@ -1,518 +0,0 @@ -/* -  Copyright IBM, Corp. 2013 - -  This file is part of GlusterFS. - -  Author: M. Mohan Kumar <mohan@in.ibm.com> - -  Based on posix-aio.c - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <lvm2app.h> -#include <sys/uio.h> - -#include <glusterfs/xlator.h> -#include <glusterfs/glusterfs.h> -#include <glusterfs/defaults.h> -#include "bd.h" -#include "bd-aio.h" - -#ifdef HAVE_LIBAIO -#include <libaio.h> -#include "bd-mem-types.h" - -struct bd_aio_cb { -    struct iocb iocb; -    call_frame_t *frame; -    struct iobuf *iobuf; -    struct iobref *iobref; -    struct iatt prebuf; -    int op; -    off_t offset; -    fd_t *fd; -}; - -void -__bd_fd_set_odirect(fd_t *fd, bd_fd_t *bd_fd, int opflags, off_t offset, -                    size_t size) -{ -    int odirect = 0; -    int flags = 0; -    int ret = 0; - -    odirect = bd_fd->odirect; - -    if ((fd->flags | opflags) & O_DIRECT) { -        /* if instructed, use O_DIRECT always */ -        odirect = 1; -    } else { -        /* else use O_DIRECT when feasible */ -        if ((offset | size) & 0xfff) -            odirect = 0; -        else -            odirect = 1; -    } - -    if (!odirect && bd_fd->odirect) { -        flags = fcntl(bd_fd->fd, F_GETFL); -        ret = fcntl(bd_fd->fd, F_SETFL, (flags & (~O_DIRECT))); -        bd_fd->odirect = 0; -    } - -    if (odirect && !bd_fd->odirect) { -        flags = fcntl(bd_fd->fd, F_GETFL); -        ret = fcntl(bd_fd->fd, F_SETFL, (flags | O_DIRECT)); -        bd_fd->odirect = 1; -    } - -    if (ret) { -        gf_log(THIS->name, GF_LOG_WARNING, -               "fcntl() failed (%s). fd=%d flags=%d pfd->odirect=%d", -               strerror(errno), bd_fd->fd, flags, bd_fd->odirect); -    } -} - -int -bd_aio_readv_complete(struct bd_aio_cb *paiocb, int res, int res2) -{ -    call_frame_t *frame = NULL; -    xlator_t *this = NULL; -    struct iobuf *iobuf = NULL; -    struct iatt postbuf = { -        0, -    }; -    int op_ret = -1; -    int op_errno = 0; -    struct iovec iov; -    struct iobref *iobref = NULL; -    off_t offset = 0; -    bd_attr_t *bdatt = NULL; - -    frame = paiocb->frame; -    this = frame->this; -    iobuf = paiocb->iobuf; -    offset = paiocb->offset; - -    if (res < 0) { -        op_ret = -1; -        op_errno = -res; -        gf_log(this->name, GF_LOG_ERROR, -               "readv(async) failed fd=%p,size=%lu,offset=%llu (%d/%s)", -               paiocb->fd, paiocb->iocb.u.c.nbytes, -               (unsigned long long)paiocb->offset, res, strerror(op_errno)); -        goto out; -    } - -    bd_inode_ctx_get(paiocb->fd->inode, this, &bdatt); -    memcpy(&postbuf, &bdatt->iatt, sizeof(struct iatt)); - -    op_ret = res; -    op_errno = 0; - -    iobref = iobref_new(); -    if (!iobref) { -        op_ret = -1; -        op_errno = ENOMEM; -        goto out; -    } - -    iobref_add(iobref, iobuf); - -    iov.iov_base = iobuf_ptr(iobuf); -    iov.iov_len = op_ret; - -    /* Hack to notify higher layers of EOF. */ -    if (!postbuf.ia_size || (offset + iov.iov_len) >= postbuf.ia_size) -        op_errno = ENOENT; - -out: -    STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, &iov, 1, &postbuf, -                        iobref, NULL); -    if (iobuf) -        iobuf_unref(iobuf); -    if (iobref) -        iobref_unref(iobref); - -    GF_FREE(paiocb); - -    return 0; -} - -int -bd_aio_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -             off_t offset, uint32_t flags, dict_t *xdata) -{ -    int32_t op_errno = EINVAL; -    int _fd = -1; -    struct iobuf *iobuf = NULL; -    bd_fd_t *bd_fd = NULL; -    int ret = -1; -    struct bd_aio_cb *paiocb = NULL; -    bd_priv_t *priv = NULL; -    struct iocb *iocb = NULL; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); - -    priv = this->private; - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd) { -        STACK_WIND(frame, default_readv_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, -                   xdata); -        return 0; -    } -    _fd = bd_fd->fd; -    bd_inode_ctx_get(fd->inode, this, &bdatt); -    if (!size) { -        op_errno = EINVAL; -        gf_log(this->name, GF_LOG_WARNING, "size=%" GF_PRI_SIZET, size); -        goto err; -    } - -    iobuf = iobuf_get2(this->ctx->iobuf_pool, size); -    if (!iobuf) { -        op_errno = ENOMEM; -        goto err; -    } - -    paiocb = GF_CALLOC(1, sizeof(*paiocb), gf_bd_aio_cb); -    if (!paiocb) { -        op_errno = ENOMEM; -        goto err; -    } - -    paiocb->frame = frame; -    paiocb->iobuf = iobuf; -    paiocb->offset = offset; -    paiocb->op = GF_FOP_READ; -    paiocb->fd = fd; - -    paiocb->iocb.data = paiocb; -    paiocb->iocb.aio_fildes = _fd; -    paiocb->iocb.aio_lio_opcode = IO_CMD_PREAD; -    paiocb->iocb.aio_reqprio = 0; -    paiocb->iocb.u.c.buf = iobuf_ptr(iobuf); -    paiocb->iocb.u.c.nbytes = size; -    paiocb->iocb.u.c.offset = offset; - -    iocb = &paiocb->iocb; - -    LOCK(&fd->lock); -    { -        __bd_fd_set_odirect(fd, bd_fd, flags, offset, size); - -        ret = io_submit(priv->ctxp, 1, &iocb); -    } -    UNLOCK(&fd->lock); - -    if (ret != 1) { -        gf_log(this->name, GF_LOG_ERROR, "io_submit() returned %d", ret); -        op_errno = -ret; -        goto err; -    } - -    return 0; -err: -    STACK_UNWIND_STRICT(readv, frame, -1, op_errno, 0, 0, 0, 0, 0); -    if (iobuf) -        iobuf_unref(iobuf); - -    if (paiocb) -        GF_FREE(paiocb); - -    return 0; -} - -int -bd_aio_writev_complete(struct bd_aio_cb *paiocb, int res, int res2) -{ -    call_frame_t *frame = NULL; -    xlator_t *this = NULL; -    struct iatt prebuf = { -        0, -    }; -    struct iatt postbuf = { -        0, -    }; -    int op_ret = -1; -    int op_errno = 0; -    bd_attr_t *bdatt = NULL; - -    frame = paiocb->frame; -    prebuf = paiocb->prebuf; -    this = frame->this; - -    if (res < 0) { -        op_ret = -1; -        op_errno = -res; -        gf_log(this->name, GF_LOG_ERROR, -               "writev(async) failed fd=%p,offset=%llu (%d/%s)", paiocb->fd, -               (unsigned long long)paiocb->offset, res, strerror(op_errno)); - -        goto out; -    } - -    bd_inode_ctx_get(paiocb->fd->inode, this, &bdatt); -    bd_update_amtime(&bdatt->iatt, GF_SET_ATTR_MTIME); -    memcpy(&postbuf, &bdatt->iatt, sizeof(struct iatt)); - -    op_ret = res; -    op_errno = 0; - -out: -    STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, &prebuf, &postbuf, -                        NULL); - -    if (paiocb->iobref) -        iobref_unref(paiocb->iobref); -    GF_FREE(paiocb); - -    return 0; -} - -int -bd_aio_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *iov, -              int count, off_t offset, uint32_t flags, struct iobref *iobref, -              dict_t *xdata) -{ -    int32_t op_errno = EINVAL; -    int _fd = -1; -    bd_fd_t *bd_fd = NULL; -    int ret = -1; -    struct bd_aio_cb *paiocb = NULL; -    bd_priv_t *priv = NULL; -    struct iocb *iocb = NULL; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, err); -    VALIDATE_OR_GOTO(this, err); -    VALIDATE_OR_GOTO(fd, err); - -    priv = this->private; - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd) { -        STACK_WIND(frame, default_writev_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->writev, fd, iov, count, offset, -                   flags, iobref, xdata); -        return 0; -    } - -    bd_inode_ctx_get(fd->inode, this, &bdatt); - -    _fd = bd_fd->fd; - -    paiocb = GF_CALLOC(1, sizeof(*paiocb), gf_bd_aio_cb); -    if (!paiocb) { -        op_errno = ENOMEM; -        goto err; -    } - -    paiocb->frame = frame; -    paiocb->offset = offset; -    paiocb->op = GF_FOP_WRITE; -    paiocb->fd = fd; - -    paiocb->iocb.data = paiocb; -    paiocb->iocb.aio_fildes = _fd; -    paiocb->iobref = iobref_ref(iobref); -    paiocb->iocb.aio_lio_opcode = IO_CMD_PWRITEV; -    paiocb->iocb.aio_reqprio = 0; -    paiocb->iocb.u.v.vec = iov; -    paiocb->iocb.u.v.nr = count; -    paiocb->iocb.u.v.offset = offset; - -    iocb = &paiocb->iocb; - -    memcpy(&paiocb->prebuf, &bdatt->iatt, sizeof(struct iatt)); -    LOCK(&fd->lock); -    { -        __bd_fd_set_odirect(fd, bd_fd, flags, offset, iov_length(iov, count)); - -        ret = io_submit(priv->ctxp, 1, &iocb); -    } -    UNLOCK(&fd->lock); - -    if (ret != 1) { -        gf_log(this->name, GF_LOG_ERROR, "io_submit() returned %d", ret); -        op_errno = -ret; -        goto err; -    } - -    return 0; -err: -    STACK_UNWIND_STRICT(writev, frame, -1, op_errno, 0, 0, 0); - -    if (paiocb) { -        if (paiocb->iobref) -            iobref_unref(paiocb->iobref); -        GF_FREE(paiocb); -    } - -    return 0; -} - -void * -bd_aio_thread(void *data) -{ -    xlator_t *this = NULL; -    bd_priv_t *priv = NULL; -    int ret = 0; -    int i = 0; -    struct io_event *event = NULL; -    struct bd_aio_cb *paiocb = NULL; -    struct io_event events[BD_AIO_MAX_NR_GETEVENTS]; -    struct timespec ts = { -        0, -    }; - -    this = data; -    THIS = this; -    priv = this->private; - -    ts.tv_sec = 5; -    for (;;) { -        memset(&events[0], 0, sizeof(events)); -        ret = io_getevents(priv->ctxp, 1, BD_AIO_MAX_NR_GETEVENTS, &events[0], -                           &ts); -        if (ret < 0) { -            if (ret == -EINTR) -                continue; -            gf_log(this->name, GF_LOG_ERROR, -                   "io_getevents() returned %d, exiting", ret); -            break; -        } - -        for (i = 0; i < ret; i++) { -            event = &events[i]; - -            paiocb = event->data; - -            switch (paiocb->op) { -                case GF_FOP_READ: -                    bd_aio_readv_complete(paiocb, event->res, event->res2); -                    break; -                case GF_FOP_WRITE: -                    bd_aio_writev_complete(paiocb, event->res, event->res2); -                    break; -                default: -                    gf_log(this->name, GF_LOG_ERROR, -                           "unknown op %d found in piocb", paiocb->op); -                    break; -            } -        } -    } - -    return NULL; -} - -int -bd_aio_init(xlator_t *this) -{ -    bd_priv_t *priv = NULL; -    int ret = 0; - -    priv = this->private; - -    ret = io_setup(BD_AIO_MAX_NR_EVENTS, &priv->ctxp); -    if ((ret == -1 && errno == ENOSYS) || ret == -ENOSYS) { -        gf_log(this->name, GF_LOG_WARNING, -               "Linux AIO not available at run-time." -               " Continuing with synchronous IO"); -        ret = 0; -        goto out; -    } - -    if (ret < 0) { -        gf_log(this->name, GF_LOG_WARNING, -               "io_setup() failed. ret=%d, errno=%d", ret, errno); -        goto out; -    } - -    ret = gf_thread_create(&priv->aiothread, NULL, bd_aio_thread, this, -                           "bdaio"); -    if (ret != 0) { -        io_destroy(priv->ctxp); -        goto out; -    } - -    this->fops->readv = bd_aio_readv; -    this->fops->writev = bd_aio_writev; -out: -    return ret; -} - -int -bd_aio_on(xlator_t *this) -{ -    bd_priv_t *priv = NULL; -    int ret = 0; - -    priv = this->private; - -    if (!priv->aio_init_done) { -        ret = bd_aio_init(this); -        if (ret == 0) -            priv->aio_capable = _gf_true; -        else -            priv->aio_capable = _gf_false; -        priv->aio_init_done = _gf_true; -    } - -    if (priv->aio_capable) { -        this->fops->readv = bd_aio_readv; -        this->fops->writev = bd_aio_writev; -    } - -    return ret; -} - -int -bd_aio_off(xlator_t *this) -{ -    this->fops->readv = bd_readv; -    this->fops->writev = bd_writev; - -    return 0; -} - -#else - -int -bd_aio_on(xlator_t *this) -{ -    gf_log(this->name, GF_LOG_INFO, -           "Linux AIO not available at build-time." -           " Continuing with synchronous IO"); -    return 0; -} - -int -bd_aio_off(xlator_t *this) -{ -    gf_log(this->name, GF_LOG_INFO, -           "Linux AIO not available at build-time." -           " Continuing with synchronous IO"); -    return 0; -} - -void -__bd_fd_set_odirect(fd_t *fd, struct bd_fd *pfd, int opflags, off_t offset, -                    size_t size) -{ -    xlator_t *this = THIS; -    gf_log(this->name, GF_LOG_INFO, -           "Linux AIO not available at build-time." -           " Continuing with synchronous IO"); -    return; -} -#endif diff --git a/xlators/storage/bd/src/bd-aio.h b/xlators/storage/bd/src/bd-aio.h deleted file mode 100644 index 23457673383..00000000000 --- a/xlators/storage/bd/src/bd-aio.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -   Copyright IBM, Corp. 2013 - -   This file is part of GlusterFS. - -   This file is licensed to you under your choice of the GNU Lesser -   General Public License, version 3 or any later version (LGPLv3 or -   later), or the GNU General Public License, version 2 (GPLv2), in all -   cases as published by the Free Software Foundation. -*/ -#ifndef _BD_AIO_H -#define _BD_AIO_H - -#include <glusterfs/xlator.h> -#include <glusterfs/glusterfs.h> - -/* - * Maximum number of concurrently submitted IO events. The heaviest load - * GlusterFS has been able to handle had 60-80 concurrent calls - */ -#define BD_AIO_MAX_NR_EVENTS 256 - -/* Maximum number of completed IO operations to reap per getevents syscall */ -#define BD_AIO_MAX_NR_GETEVENTS 16 - -int -bd_aio_on(xlator_t *this); -int -bd_aio_off(xlator_t *this); - -int -bd_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -         off_t offset, uint32_t flags, dict_t *xdata); - -int -bd_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, -          int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, -          dict_t *xdata); - -#endif /* !_BD_AIO_H */ diff --git a/xlators/storage/bd/src/bd-helper.c b/xlators/storage/bd/src/bd-helper.c deleted file mode 100644 index 74c979ace00..00000000000 --- a/xlators/storage/bd/src/bd-helper.c +++ /dev/null @@ -1,1073 +0,0 @@ -#include <lvm2app.h> -#ifdef HAVE_LIBAIO -#include <libaio.h> -#endif -#include <linux/fs.h> -#include <sys/ioctl.h> -#include "bd.h" -#include "bd-mem-types.h" -#include <glusterfs/run.h> -#include <glusterfs/lvm-defaults.h> -#include <glusterfs/syscall.h> - -int -bd_inode_ctx_set(inode_t *inode, xlator_t *this, bd_attr_t *ctx) -{ -    int ret = -1; -    uint64_t ctx_int = 0; - -    GF_VALIDATE_OR_GOTO(this->name, inode, out); -    GF_VALIDATE_OR_GOTO(this->name, ctx, out); - -    ctx_int = (long)ctx; -    ret = inode_ctx_set(inode, this, &ctx_int); -out: -    return ret; -} - -int -bd_inode_ctx_get(inode_t *inode, xlator_t *this, bd_attr_t **ctx) -{ -    int ret = -1; -    uint64_t ctx_int = 0; - -    GF_VALIDATE_OR_GOTO(this->name, inode, out); -    ret = inode_ctx_get(inode, this, &ctx_int); -    if (ret) -        return ret; -    if (ctx) -        *ctx = (bd_attr_t *)ctx_int; -out: -    return ret; -} - -void -bd_local_free(xlator_t *this, bd_local_t *local) -{ -    if (!local) -        return; -    if (local->fd) -        fd_unref(local->fd); -    else if (local->loc.path) -        loc_wipe(&local->loc); -    if (local->dict) -        dict_unref(local->dict); -    if (local->inode) -        inode_unref(local->inode); -    if (local->bdatt) { -        GF_FREE(local->bdatt->type); -        GF_FREE(local->bdatt); -    } -    mem_put(local); -    local = NULL; -} - -bd_local_t * -bd_local_init(call_frame_t *frame, xlator_t *this) -{ -    frame->local = mem_get0(this->local_pool); -    if (!frame->local) -        return NULL; - -    return frame->local; -} - -/* - * VG are set with the tag in GF_XATTR_VOL_ID_KEY:<uuid> format. - * This function validates this tag against volume-uuid. Also goes - * through LV list to find out if a thin-pool is configured or not. - */ -int -bd_scan_vg(xlator_t *this, bd_priv_t *priv) -{ -    vg_t brick = NULL; -    data_t *tmp_data = NULL; -    struct dm_list *tags = NULL; -    int op_ret = -1; -    uuid_t dict_uuid = { -        0, -    }; -    uuid_t vg_uuid = { -        0, -    }; -    gf_boolean_t uuid = _gf_false; -    lvm_str_list_t *strl = NULL; -    struct dm_list *lv_dm_list = NULL; -    lv_list_t *lv_list = NULL; -    struct dm_list *dm_seglist = NULL; -    lvseg_list_t *seglist = NULL; -    lvm_property_value_t prop = { -        0, -    }; -    gf_boolean_t thin = _gf_false; -    const char *lv_name = NULL; - -    brick = lvm_vg_open(priv->handle, priv->vg, "w", 0); -    if (!brick) { -        gf_log(this->name, GF_LOG_CRITICAL, "VG %s is not found", priv->vg); -        return ENOENT; -    } - -    lv_dm_list = lvm_vg_list_lvs(brick); -    if (!lv_dm_list) -        goto check; - -    dm_list_iterate_items(lv_list, lv_dm_list) -    { -        dm_seglist = lvm_lv_list_lvsegs(lv_list->lv); -        if (!dm_seglist) -            continue; -        dm_list_iterate_items(seglist, dm_seglist) -        { -            prop = lvm_lvseg_get_property(seglist->lvseg, "segtype"); -            if (!prop.is_valid || !prop.value.string) -                continue; -            if (!strcmp(prop.value.string, "thin-pool")) { -                thin = _gf_true; -                lv_name = lvm_lv_get_name(lv_list->lv); -                priv->pool = gf_strdup(lv_name); -                gf_log(THIS->name, GF_LOG_INFO, -                       "Thin Pool " -                       "\"%s\" will be used for thin LVs", -                       lv_name); -                break; -            } -        } -    } - -check: -    /* If there is no volume-id set in dict, we can't validate */ -    tmp_data = dict_get(this->options, "volume-id"); -    if (!tmp_data) { -        op_ret = 0; -        goto out; -    } - -    op_ret = gf_uuid_parse(tmp_data->data, dict_uuid); -    if (op_ret < 0) { -        gf_log(this->name, GF_LOG_ERROR, -               "wrong volume-id (%s) set in volume file", tmp_data->data); -        op_ret = -1; -        goto out; -    } - -    tags = lvm_vg_get_tags(brick); -    if (!tags) { /* no tags in the VG */ -        gf_log(this->name, GF_LOG_ERROR, -               "Extended attribute trusted.glusterfs." -               "volume-id is absent"); -        op_ret = -1; -        goto out; -    } -    dm_list_iterate_items(strl, tags) -    { -        if (!strncmp(strl->str, GF_XATTR_VOL_ID_KEY, -                     SLEN(GF_XATTR_VOL_ID_KEY))) { -            uuid = _gf_true; -            break; -        } -    } -    /* UUID tag is not set in VG */ -    if (!uuid) { -        gf_log(this->name, GF_LOG_ERROR, -               "Extended attribute trusted.glusterfs." -               "volume-id is absent"); -        op_ret = -1; -        goto out; -    } - -    op_ret = gf_uuid_parse(strl->str + SLEN(GF_XATTR_VOL_ID_KEY) + 1, vg_uuid); -    if (op_ret < 0) { -        gf_log(this->name, GF_LOG_ERROR, "wrong volume-id (%s) set in VG", -               strl->str); -        op_ret = -1; -        goto out; -    } -    if (gf_uuid_compare(dict_uuid, vg_uuid)) { -        gf_log(this->name, GF_LOG_ERROR, -               "mismatching volume-id (%s) received. " -               "already is a part of volume %s ", -               tmp_data->data, vg_uuid); -        op_ret = -1; -        goto out; -    } - -    op_ret = 0; - -out: -    lvm_vg_close(brick); - -    if (!thin) -        gf_log(THIS->name, GF_LOG_WARNING, -               "No thin pool found in " -               "VG %s\n", -               priv->vg); -    else -        priv->caps |= BD_CAPS_THIN; - -    return op_ret; -} - -/* FIXME: Move this code to common place, so posix and bd xlator can use */ -char * -page_aligned_alloc(size_t size, char **aligned_buf) -{ -    char *alloc_buf = NULL; -    char *buf = NULL; - -    alloc_buf = GF_CALLOC(1, (size + ALIGN_SIZE), gf_common_mt_char); -    if (!alloc_buf) -        return NULL; -    /* page aligned buffer */ -    buf = GF_ALIGN_BUF(alloc_buf, ALIGN_SIZE); -    *aligned_buf = buf; - -    return alloc_buf; -} - -static int -__bd_fd_ctx_get(xlator_t *this, fd_t *fd, bd_fd_t **bdfd_p) -{ -    int ret = -1; -    int _fd = -1; -    char *devpath = NULL; -    bd_fd_t *bdfd = NULL; -    uint64_t tmp_bdfd = 0; -    bd_priv_t *priv = this->private; -    bd_gfid_t gfid = { -        0, -    }; -    bd_attr_t *bdatt = NULL; - -    /* not bd file */ -    if (fd->inode->ia_type != IA_IFREG || -        bd_inode_ctx_get(fd->inode, this, &bdatt)) -        return 0; - -    ret = __fd_ctx_get(fd, this, &tmp_bdfd); -    if (ret == 0) { -        bdfd = (void *)(long)tmp_bdfd; -        *bdfd_p = bdfd; -        return 0; -    } - -    uuid_utoa_r(fd->inode->gfid, gfid); -    gf_asprintf(&devpath, "/dev/%s/%s", priv->vg, gfid); -    if (!devpath) -        goto out; - -    _fd = open(devpath, O_RDWR | O_LARGEFILE, 0); -    if (_fd < 0) { -        ret = errno; -        gf_log(this->name, GF_LOG_ERROR, "open on %s: %s", devpath, -               strerror(ret)); -        goto out; -    } -    bdfd = GF_CALLOC(1, sizeof(bd_fd_t), gf_bd_fd); -    BD_VALIDATE_MEM_ALLOC(bdfd, ret, out); - -    bdfd->fd = _fd; -    bdfd->flag = O_RDWR | O_LARGEFILE; -    if (__fd_ctx_set(fd, this, (uint64_t)(long)bdfd) < 0) { -        gf_log(this->name, GF_LOG_WARNING, "failed to set the fd context fd=%p", -               fd); -        goto out; -    } - -    *bdfd_p = bdfd; - -    ret = 0; -out: -    GF_FREE(devpath); -    if (ret) { -        if (_fd >= 0) -            sys_close(_fd); -        GF_FREE(bdfd); -    } -    return ret; -} - -int -bd_fd_ctx_get(xlator_t *this, fd_t *fd, bd_fd_t **bdfd) -{ -    int ret; - -    /* FIXME: Is it ok to fd->lock here ? */ -    LOCK(&fd->lock); -    { -        ret = __bd_fd_ctx_get(this, fd, bdfd); -    } -    UNLOCK(&fd->lock); - -    return ret; -} - -/* - * Validates if LV exists for given inode or not. - * Returns 0 if LV exists and size also matches. - * If LV does not exist -1 returned - * If LV size mismatches, returns 1 also lv_size is updated with actual - * size - */ -int -bd_validate_bd_xattr(xlator_t *this, char *bd, char **type, uint64_t *lv_size, -                     uuid_t uuid) -{ -    char *path = NULL; -    int ret = -1; -    bd_gfid_t gfid = { -        0, -    }; -    bd_priv_t *priv = this->private; -    struct stat stbuf = { -        0, -    }; -    uint64_t size = 0; -    vg_t vg = NULL; -    lv_t lv = NULL; -    char *bytes = NULL; - -    bytes = strrchr(bd, ':'); -    if (bytes) { -        *bytes = '\0'; -        bytes++; -        gf_string2bytesize_uint64(bytes, &size); -    } - -    if (strcmp(bd, BD_LV) && strcmp(bd, BD_THIN)) { -        gf_log(this->name, GF_LOG_WARNING, "invalid xattr %s", bd); -        return -1; -    } -    *type = gf_strdup(bd); - -    /* -     * Check if LV really exist, there could be a failure -     * after setxattr and successful LV creation -     */ -    uuid_utoa_r(uuid, gfid); -    gf_asprintf(&path, "/dev/%s/%s", priv->vg, gfid); -    if (!path) { -        gf_log(this->name, GF_LOG_WARNING, "insufficient memory"); -        return 0; -    } - -    /* Destination file does not exist */ -    if (sys_stat(path, &stbuf)) { -        gf_log(this->name, GF_LOG_WARNING, "lstat failed for path %s", path); -        GF_FREE(path); -        return -1; -    } - -    vg = lvm_vg_open(priv->handle, priv->vg, "r", 0); -    if (!vg) { -        gf_log(this->name, GF_LOG_WARNING, "VG %s does not exist?", priv->vg); -        ret = -1; -        goto out; -    } - -    lv = lvm_lv_from_name(vg, gfid); -    if (!lv) { -        gf_log(this->name, GF_LOG_WARNING, "LV %s does not exist", gfid); -        ret = -1; -        goto out; -    } - -    *lv_size = lvm_lv_get_size(lv); -    if (size == *lv_size) { -        ret = 0; -        goto out; -    } - -    ret = 1; - -out: -    if (vg) -        lvm_vg_close(vg); - -    GF_FREE(path); -    return ret; -} - -static int -create_thin_lv(char *vg, char *pool, char *lv, uint64_t extent) -{ -    int ret = -1; -    runner_t runner = { -        0, -    }; -    char *path = NULL; -    struct stat stat = { -        0, -    }; - -    runinit(&runner); -    runner_add_args(&runner, LVM_CREATE, NULL); -    runner_add_args(&runner, "--thin", NULL); -    runner_argprintf(&runner, "%s/%s", vg, pool); -    runner_add_args(&runner, "--name", NULL); -    runner_argprintf(&runner, "%s", lv); -    runner_add_args(&runner, "--virtualsize", NULL); -    runner_argprintf(&runner, "%ldB", extent); -    runner_start(&runner); -    runner_end(&runner); - -    gf_asprintf(&path, "/dev/%s/%s", vg, lv); -    if (!path) { -        ret = ENOMEM; -        goto out; -    } -    if (sys_lstat(path, &stat) < 0) -        ret = EAGAIN; -    else -        ret = 0; -out: -    GF_FREE(path); -    return ret; -} - -int -bd_create(uuid_t uuid, uint64_t size, char *type, bd_priv_t *priv) -{ -    int ret = 0; -    vg_t vg = NULL; -    bd_gfid_t gfid = { -        0, -    }; - -    uuid_utoa_r(uuid, gfid); - -    if (!strcmp(type, BD_THIN)) -        return create_thin_lv(priv->vg, priv->pool, gfid, size); - -    vg = lvm_vg_open(priv->handle, priv->vg, "w", 0); -    if (!vg) { -        gf_log(THIS->name, GF_LOG_WARNING, "opening VG %s failed", priv->vg); -        return ENOENT; -    } - -    if (!lvm_vg_create_lv_linear(vg, gfid, size)) { -        gf_log(THIS->name, GF_LOG_WARNING, -               "lvm_vg_create_lv_linear " -               "failed"); -        ret = errno; -    } - -    lvm_vg_close(vg); - -    return ret; -} - -int32_t -bd_resize(bd_priv_t *priv, uuid_t uuid, size_t size) -{ -    uint64_t new_size = 0; -    runner_t runner = { -        0, -    }; -    bd_gfid_t gfid = { -        0, -    }; -    int ret = 0; -    vg_t vg = NULL; -    lv_t lv = NULL; - -    uuid_utoa_r(uuid, gfid); - -    runinit(&runner); - -    runner_add_args(&runner, LVM_RESIZE, NULL); -    runner_argprintf(&runner, "%s/%s", priv->vg, gfid); -    runner_argprintf(&runner, "-L%ldb", size); -    runner_add_args(&runner, "-f", NULL); - -    runner_start(&runner); -    runner_end(&runner); - -    vg = lvm_vg_open(priv->handle, priv->vg, "w", 0); -    if (!vg) { -        gf_log(THIS->name, GF_LOG_WARNING, "opening VG %s failed", priv->vg); -        return EAGAIN; -    } - -    lv = lvm_lv_from_name(vg, gfid); -    if (!lv) { -        gf_log(THIS->name, GF_LOG_WARNING, "LV %s not found", gfid); -        ret = EIO; -        goto out; -    } -    new_size = lvm_lv_get_size(lv); - -    if (new_size != size) { -        gf_log(THIS->name, GF_LOG_WARNING, -               "resized LV size %" PRIu64 -               " does " -               "not match requested size %zd", -               new_size, size); -        ret = EIO; -    } - -out: -    lvm_vg_close(vg); -    return ret; -} - -uint64_t -bd_get_default_extent(bd_priv_t *priv) -{ -    vg_t vg = NULL; -    uint64_t size = 0; - -    vg = lvm_vg_open(priv->handle, priv->vg, "w", 0); -    if (!vg) { -        gf_log(THIS->name, GF_LOG_WARNING, "opening VG %s failed", priv->vg); -        return 0; -    } - -    size = lvm_vg_get_extent_size(vg); - -    lvm_vg_close(vg); - -    return size; -} - -/* - * Adjusts the user specified size to VG specific extent size - */ -uint64_t -bd_adjust_size(bd_priv_t *priv, size_t size) -{ -    uint64_t extent = 0; -    uint64_t nr_ex = 0; - -    extent = bd_get_default_extent(priv); -    if (!extent) -        return 0; - -    nr_ex = size / extent; -    if (size % extent) -        nr_ex++; - -    size = extent * nr_ex; - -    return size; -} - -int -bd_delete_lv(bd_priv_t *priv, const char *lv_name, int *op_errno) -{ -    vg_t vg = NULL; -    lv_t lv = NULL; -    int ret = -1; - -    *op_errno = 0; -    vg = lvm_vg_open(priv->handle, priv->vg, "w", 0); -    if (!vg) { -        gf_log(THIS->name, GF_LOG_WARNING, "opening VG %s failed", priv->vg); -        *op_errno = ENOENT; -        return -1; -    } -    lv = lvm_lv_from_name(vg, lv_name); -    if (!lv) { -        gf_log(THIS->name, GF_LOG_WARNING, "No such LV %s", lv_name); -        *op_errno = ENOENT; -        goto out; -    } -    ret = lvm_vg_remove_lv(lv); -    if (ret < 0) { -        gf_log(THIS->name, GF_LOG_WARNING, "removing LV %s failed", lv_name); -        *op_errno = errno; -        goto out; -    } -out: -    lvm_vg_close(vg); - -    return ret; -} - -void -bd_update_amtime(struct iatt *iatt, int flag) -{ -    struct timespec ts = { -        0, -    }; - -    clock_gettime(CLOCK_REALTIME, &ts); -    if (flag & GF_SET_ATTR_ATIME) { -        iatt->ia_atime = ts.tv_sec; -        iatt->ia_atime_nsec = ts.tv_nsec; -    } -    if (flag & GF_SET_ATTR_MTIME) { -        iatt->ia_mtime = ts.tv_sec; -        iatt->ia_mtime_nsec = ts.tv_nsec; -    } -} - -int -bd_snapshot_create(bd_local_t *local, bd_priv_t *priv) -{ -    char *path = NULL; -    bd_gfid_t dest = { -        0, -    }; -    bd_gfid_t origin = { -        0, -    }; -    int ret = 0; -    runner_t runner = { -        0, -    }; -    struct stat stat = { -        0, -    }; - -    uuid_utoa_r(local->dloc->gfid, dest); -    uuid_utoa_r(local->loc.gfid, origin); - -    gf_asprintf(&path, "/dev/%s/%s", priv->vg, dest); -    if (!path) { -        gf_log(THIS->name, GF_LOG_WARNING, "Insufficient memory"); -        return ENOMEM; -    } - -    runinit(&runner); -    runner_add_args(&runner, LVM_CREATE, NULL); -    runner_add_args(&runner, "--snapshot", NULL); -    runner_argprintf(&runner, "/dev/%s/%s", priv->vg, origin); -    runner_add_args(&runner, "--name", NULL); -    runner_argprintf(&runner, "%s", dest); -    if (strcmp(local->bdatt->type, BD_THIN)) -        runner_argprintf(&runner, "-L%ldB", local->size); -    runner_start(&runner); -    runner_end(&runner); - -    if (sys_lstat(path, &stat) < 0) -        ret = EIO; - -    GF_FREE(path); -    return ret; -} - -int -bd_clone(bd_local_t *local, bd_priv_t *priv) -{ -    int ret = ENOMEM; -    int fd1 = -1; -    int fd2 = -1; -    int i = 0; -    char *buff = NULL; -    ssize_t bytes = 0; -    char *spath = NULL; -    char *dpath = NULL; -    struct iovec *vec = NULL; -    bd_gfid_t source = { -        0, -    }; -    bd_gfid_t dest = { -        0, -    }; -    void *bufp[IOV_NR] = { -        0, -    }; - -    vec = GF_CALLOC(IOV_NR, sizeof(struct iovec), gf_common_mt_iovec); -    if (!vec) -        return ENOMEM; - -    for (i = 0; i < IOV_NR; i++) { -        bufp[i] = page_aligned_alloc(IOV_SIZE, &buff); -        if (!buff) -            goto out; -        vec[i].iov_base = buff; -        vec[i].iov_len = IOV_SIZE; -    } - -    uuid_utoa_r(local->loc.gfid, source); -    uuid_utoa_r(local->dloc->gfid, dest); - -    gf_asprintf(&spath, "/dev/%s/%s", priv->vg, source); -    gf_asprintf(&dpath, "/dev/%s/%s", priv->vg, dest); -    if (!spath || !dpath) -        goto out; - -    ret = bd_create(local->dloc->gfid, local->size, local->bdatt->type, priv); -    if (ret) -        goto out; - -    fd1 = open(spath, O_RDONLY | O_DIRECT); -    if (fd1 < 0) { -        ret = errno; -        goto out; -    } -    fd2 = open(dpath, O_WRONLY | O_DIRECT); -    if (fd2 < 0) { -        ret = errno; -        goto out; -    } - -    while (1) { -        bytes = sys_readv(fd1, vec, IOV_NR); -        if (bytes < 0) { -            ret = errno; -            gf_log(THIS->name, GF_LOG_WARNING, "read failed: %s", -                   strerror(ret)); -            goto out; -        } -        if (!bytes) -            break; -        bytes = sys_writev(fd2, vec, IOV_NR); -        if (bytes < 0) { -            ret = errno; -            gf_log(THIS->name, GF_LOG_WARNING, "write failed: %s", -                   strerror(ret)); -            goto out; -        } -    } -    ret = 0; - -out: -    for (i = 0; i < IOV_NR; i++) -        GF_FREE(bufp[i]); -    GF_FREE(vec); - -    if (fd1 != -1) -        sys_close(fd1); -    if (fd2 != -1) -        sys_close(fd2); - -    GF_FREE(spath); -    GF_FREE(dpath); - -    return ret; -} - -/* - * Merges snapshot LV to origin LV and returns status - */ -int -bd_merge(bd_priv_t *priv, uuid_t gfid) -{ -    bd_gfid_t dest = { -        0, -    }; -    char *path = NULL; -    struct stat stat = { -        0, -    }; -    runner_t runner = { -        0, -    }; -    int ret = 0; - -    uuid_utoa_r(gfid, dest); -    gf_asprintf(&path, "/dev/%s/%s", priv->vg, dest); - -    runinit(&runner); -    runner_add_args(&runner, LVM_CONVERT, NULL); -    runner_add_args(&runner, "--merge", NULL); -    runner_argprintf(&runner, "%s", path); -    runner_start(&runner); -    runner_end(&runner); - -    if (!sys_lstat(path, &stat)) -        ret = EIO; - -    GF_FREE(path); - -    return ret; -} - -int -bd_get_origin(bd_priv_t *priv, loc_t *loc, fd_t *fd, dict_t *dict) -{ -    vg_t brick = NULL; -    lvm_property_value_t prop = { -        0, -    }; -    lv_t lv = NULL; -    int ret = -1; -    bd_gfid_t gfid = { -        0, -    }; -    inode_t *inode = NULL; -    char *origin = NULL; - -    brick = lvm_vg_open(priv->handle, priv->vg, "w", 0); -    if (!brick) { -        gf_log(THIS->name, GF_LOG_CRITICAL, "VG %s is not found", priv->vg); -        return ENOENT; -    } - -    if (fd) -        inode = fd->inode; -    else -        inode = loc->inode; - -    uuid_utoa_r(inode->gfid, gfid); -    lv = lvm_lv_from_name(brick, gfid); -    if (!lv) { -        gf_log(THIS->name, GF_LOG_CRITICAL, "LV %s not found", gfid); -        ret = ENOENT; -        goto out; -    } - -    prop = lvm_lv_get_property(lv, "origin"); -    if (!prop.is_valid || !prop.value.string) { -        ret = ENODATA; -        goto out; -    } - -    origin = gf_strdup(prop.value.string); -    ret = dict_set_dynstr(dict, BD_ORIGIN, origin); - -out: -    lvm_vg_close(brick); -    return ret; -} - -#ifndef BLKZEROOUT - -int -bd_do_manual_zerofill(int fd, off_t offset, off_t len, int o_direct) -{ -    off_t num_vect = 0; -    off_t num_loop = 1; -    int idx = 0; -    int op_ret = -1; -    int vect_size = IOV_SIZE; -    off_t remain = 0; -    off_t extra = 0; -    struct iovec *vector = NULL; -    char *iov_base = NULL; -    char *alloc_buf = NULL; - -    if (len == 0) -        return 0; - -    if (len < IOV_SIZE) -        vect_size = len; - -    num_vect = len / (vect_size); -    remain = len % vect_size; - -    if (num_vect > MAX_NO_VECT) { -        extra = num_vect % MAX_NO_VECT; -        num_loop = num_vect / MAX_NO_VECT; -        num_vect = MAX_NO_VECT; -    } - -    vector = GF_CALLOC(num_vect, sizeof(struct iovec), gf_common_mt_iovec); -    if (!vector) -        return -1; - -    if (o_direct) { -        alloc_buf = page_aligned_alloc(vect_size, &iov_base); -        if (!alloc_buf) { -            gf_log("bd_do_manual_zerofill", GF_LOG_DEBUG, -                   "memory alloc failed, vect_size %d: %s", vect_size, -                   strerror(errno)); -            GF_FREE(vector); -            return -1; -        } -    } else { -        iov_base = GF_CALLOC(vect_size, sizeof(char), gf_common_mt_char); -        if (!iov_base) { -            GF_FREE(vector); -            return -1; -        } -    } - -    for (idx = 0; idx < num_vect; idx++) { -        vector[idx].iov_base = iov_base; -        vector[idx].iov_len = vect_size; -    } - -    if (sys_lseek(fd, offset, SEEK_SET) < 0) { -        op_ret = -1; -        goto err; -    } - -    for (idx = 0; idx < num_loop; idx++) { -        op_ret = sys_writev(fd, vector, num_vect); -        if (op_ret < 0) -            goto err; -    } -    if (extra) { -        op_ret = sys_writev(fd, vector, extra); -        if (op_ret < 0) -            goto err; -    } -    if (remain) { -        vector[0].iov_len = remain; -        op_ret = sys_writev(fd, vector, 1); -        if (op_ret < 0) -            goto err; -    } -    op_ret = 0; -err: -    if (o_direct) -        GF_FREE(alloc_buf); -    else -        GF_FREE(iov_base); -    GF_FREE(vector); -    return op_ret; -} - -#else - -/* - * Issue Linux ZEROOUT ioctl to write '0' to a scsi device at given offset - * and number of bytes. Each SCSI device's maximum write same bytes are exported - * in sysfs file. Sending ioctl request greater than this bytes results in slow - * performance. Read this file to get the maximum bytes and break down single - * ZEROOUT request into multiple ZEROOUT request not exceeding maximum bytes. - * From VG & LV name of device mapper identified and sysfs file read. - * /sys/block/<block-device>/queue/write_same_max_bytes - */ -int -bd_do_ioctl_zerofill(bd_priv_t *priv, bd_attr_t *bdatt, int fd, char *vg, -                     off_t offset, off_t len) -{ -    char *dm = NULL; -    char dmname[4096] = { -        0, -    }; -    char lvname[4096] = { -        0, -    }; -    char sysfs[4096] = { -        0, -    }; -    bd_gfid_t uuid = { -        0, -    }; -    char *p = NULL; -    off_t max_bytes = 0; -    int sysfd = -1; -    int ret = 0; -    uint64_t param[2] = {0, 0}; -    off_t nr_loop = 0; -    char buff[16] = { -        0, -    }; - -    uuid_utoa_r(bdatt->iatt.ia_gfid, uuid); -    sprintf(lvname, "/dev/%s/%s", vg, uuid); - -    ret = sys_readlink(lvname, dmname, 4096); -    if (ret < 0) { -        gf_log("bd", GF_LOG_DEBUG, "Failed to read symbolic link '%s': %s", -               lvname, strerror(errno)); -        goto skip; -    } - -    dmname[ret] = '\0'; - -    p = strrchr(dmname, '/'); -    if (p) -        dm = p + 1; -    else -        dm = dmname; - -    sprintf(sysfs, "/sys/block/%s/queue/write_same_max_bytes", dm); -    sysfd = open(sysfs, O_RDONLY); -    if (sysfd < 0) { -        gf_log("bd_do_ioctl_zerofill", GF_LOG_DEBUG, -               "sysfs file %s does not exist", lvname); -        goto skip; -    } - -    sys_read(sysfd, buff, sizeof(buff)); -    sys_close(sysfd); - -    max_bytes = atoll(buff); - -skip: -    /* -     * If requested len is less than write_same_max_bytes, -     * issue single ioctl to zeroout. Otherwise split the ioctls -     */ -    if (!max_bytes || len <= max_bytes) { -        param[0] = offset; -        param[1] = len; - -        if (ioctl(fd, BLKZEROOUT, param) < 0) -            return errno; -        return 0; -    } - -    /* Split ioctls to max write_same_max_bytes */ -    nr_loop = len / max_bytes; -    for (; nr_loop; nr_loop--) { -        param[0] = offset; -        param[1] = max_bytes; - -        if (ioctl(fd, BLKZEROOUT, param) < 0) -            return errno; - -        offset += max_bytes; -    } - -    if (!(len % max_bytes)) -        return 0; - -    param[0] = offset; -    param[1] = len % max_bytes; - -    if (ioctl(fd, BLKZEROOUT, param) < 0) -        return errno; - -    return 0; -} -#endif - -int -bd_do_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -               size_t len, struct iatt *prebuf, struct iatt *postbuf) -{ -    int ret = -1; -    bd_fd_t *bd_fd = NULL; -    bd_priv_t *priv = this->private; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(priv, out); - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0) { -        gf_log(this->name, GF_LOG_DEBUG, "bd_fd is NULL from fd=%p", fd); -        goto out; -    } - -    bd_inode_ctx_get(fd->inode, this, &bdatt); -#ifndef BLKZEROOUT -    ret = bd_do_manual_zerofill(bd_fd->fd, offset, len, bd_fd->flag & O_DIRECT); -#else -    ret = bd_do_ioctl_zerofill(priv, bdatt, bd_fd->fd, priv->vg, offset, len); -#endif -    if (ret) { -        gf_log(this->name, GF_LOG_ERROR, -               "zerofill failed on fd %d length %zu %s", bd_fd->fd, len, -               strerror(ret)); -        goto out; -    } - -    if (bd_fd->flag & (O_SYNC | O_DSYNC)) { -        ret = sys_fsync(bd_fd->fd); -        if (ret) { -            gf_log(this->name, GF_LOG_ERROR, -                   "fsync() in writev on fd %d failed: %s", bd_fd->fd, -                   strerror(errno)); -            return errno; -        } -    } - -    memcpy(prebuf, &bdatt->iatt, sizeof(struct iatt)); -    bd_update_amtime(&bdatt->iatt, GF_SET_ATTR_MTIME); -    memcpy(postbuf, &bdatt->iatt, sizeof(struct iatt)); - -out: - -    return ret; -} diff --git a/xlators/storage/bd/src/bd-mem-types.h b/xlators/storage/bd/src/bd-mem-types.h deleted file mode 100644 index 5cdbd6938e1..00000000000 --- a/xlators/storage/bd/src/bd-mem-types.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -  Copyright (c) 2008-2014 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __BD_MEM_TYPES_H__ -#define __BD_MEM_TYPES_H__ - -#include <glusterfs/mem-types.h> - -enum gf_bd_mem_types_ { -    gf_bd_private = gf_common_mt_end + 1, -    gf_bd_attr, -    gf_bd_fd, -    gf_bd_loc_t, -    gf_bd_int32_t, -    gf_bd_aio_cb, -    gf_bd_mt_end -}; - -#endif diff --git a/xlators/storage/bd/src/bd.c b/xlators/storage/bd/src/bd.c deleted file mode 100644 index 3d1fa1b6b14..00000000000 --- a/xlators/storage/bd/src/bd.c +++ /dev/null @@ -1,2426 +0,0 @@ -/* -  BD translator V2 - Exports Block devices on server side as regular -  files to client - -  Now only exporting Logical volumes supported. - -  Copyright IBM, Corp. 2013 - -  This file is part of GlusterFS. - -  Author: -  M. Mohan Kumar <mohan@in.ibm.com> - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include <lvm2app.h> -#include <openssl/md5.h> -#include <time.h> -#include <linux/fs.h> -#include <sys/ioctl.h> -#ifdef HAVE_LIBAIO -#include <libaio.h> -#endif - -#include "bd.h" -#include "bd-aio.h" -#include "bd-mem-types.h" -#include <glusterfs/defaults.h> -#include "glusterfs3-xdr.h" -#include <glusterfs/run.h> -#include "protocol-common.h" -#include <glusterfs/checksum.h> -#include <glusterfs/syscall.h> -#include <glusterfs/lvm-defaults.h> - -/* - * Call back function for setxattr and removexattr. - * does not do anything. FIXME: How to handle remove/setxattr failure - */ -int -bd_null_rmsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                       int op_ret, int op_errno, dict_t *xdata) -{ -    STACK_DESTROY(frame->root); -    return 0; -} - -/* - * returns 0 if a file is mapped to BD or not. - */ -int -bd_get_bd_info(call_frame_t *frame, xlator_t *this, dict_t *xattr, uuid_t gfid, -               char **type, uint64_t *size) -{ -    char *bd_xattr = NULL; -    char *bd = NULL; -    int ret = -1; -    loc_t loc = { -        0, -    }; -    dict_t *dict = NULL; -    char *p = NULL; -    call_frame_t *bd_frame = NULL; - -    if (!xattr) -        return 1; - -    if (dict_get_str(xattr, BD_XATTR, &p)) -        return 1; - -    bd_xattr = gf_strdup(p); - -    memcpy(loc.gfid, gfid, sizeof(uuid_t)); - -    bd_frame = copy_frame(frame); -    BD_VALIDATE_MEM_ALLOC(bd_frame, ret, out); - -    ret = bd_validate_bd_xattr(this, bd_xattr, type, size, gfid); -    if (ret < 0) { /* LV does not exist */ -        STACK_WIND(bd_frame, bd_null_rmsetxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->removexattr, &loc, BD_XATTR, NULL); - -        gf_log(this->name, GF_LOG_WARNING, -               "Mapped LV not available for posix file <gfid:%s>, " -               "deleting mapping", -               uuid_utoa(gfid)); -    } else if (ret == 1) { -        /* BD_XATTR size and LV size mismatch. Update BD_XATTR */ -        gf_asprintf(&bd, "%s:%ld", *type, *size); - -        dict = dict_new(); -        BD_VALIDATE_MEM_ALLOC(dict, ret, out); - -        ret = dict_set_dynstr(dict, BD_XATTR, bd); -        if (ret) -            goto out; - -        STACK_WIND(bd_frame, bd_null_rmsetxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setxattr, &loc, dict, 0, NULL); -    } - -out: -    dict_del(xattr, BD_XATTR); -    GF_FREE(bd_xattr); -    GF_FREE(bd); -    return ret; -} - -/* - * bd_lookup_cbk: Call back from posix_lookup. - */ -int32_t -bd_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -              int op_errno, inode_t *inode, struct iatt *buf, dict_t *xattr, -              struct iatt *postparent) -{ -    int ret = -1; -    bd_attr_t *bdatt = NULL; -    uint64_t size = 0; -    char *type = NULL; - -    /* only regular files are part of BD object */ -    if (op_ret < 0 || buf->ia_type != IA_IFREG) -        goto out; - -    /* iatt already cached */ -    if (!bd_inode_ctx_get(inode, this, &bdatt)) -        goto next; - -    if (bd_get_bd_info(frame, this, xattr, buf->ia_gfid, &type, &size)) -        goto out; - -    /* BD file, update buf */ -    bdatt = GF_CALLOC(1, sizeof(bd_attr_t), gf_bd_attr); -    if (!bdatt) { -        op_errno = ENOMEM; -        goto out; -    } -    memcpy(&bdatt->iatt, buf, sizeof(struct iatt)); -    bdatt->type = type; - -    /* Cache LV size in inode_ctx */ -    ret = bd_inode_ctx_set(inode, this, bdatt); -    if (ret < 0) { -        GF_FREE(bdatt); -        op_errno = EINVAL; -        goto out; -    } - -    bdatt->iatt.ia_size = size; -    bdatt->iatt.ia_blocks = size / 512; - -next: -    dict_del(xattr, GF_CONTENT_KEY); -    memcpy(buf, &bdatt->iatt, sizeof(struct iatt)); - -out: -    BD_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, xattr, -                    postparent); -    return 0; -} - -/* - * bd_lookup: Issues posix_lookup to find out if file is mapped to BD - * bd_lookup -> posix_lookup -> bd_lookup_cbk - */ -int32_t -bd_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) -{ -    dict_t *bd_xattr = NULL; -    bd_attr_t *bdatt = NULL; -    int op_errno = EINVAL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(loc, out); -    VALIDATE_OR_GOTO(loc->path, out); -    VALIDATE_OR_GOTO(this->private, out); - -    if (bd_inode_ctx_get(loc->inode, this, &bdatt) < 0) { -        if (!xattr_req) { -            bd_xattr = dict_new(); -            BD_VALIDATE_MEM_ALLOC(bd_xattr, op_errno, out); -            xattr_req = bd_xattr; -        } -        if (dict_set_int8(xattr_req, BD_XATTR, 1) < 0) -            goto out; -    } - -    STACK_WIND(frame, bd_lookup_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lookup, loc, xattr_req); - -    if (bd_xattr) -        dict_unref(bd_xattr); -    return 0; -out: -    BD_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); - -    return 0; -} - -int -bd_forget(xlator_t *this, inode_t *inode) -{ -    int ret = -1; -    uint64_t ctx = 0; -    bd_attr_t *bdatt = NULL; - -    ret = bd_inode_ctx_get(inode, this, &bdatt); -    if (!ret) { -        inode_ctx_del(inode, this, &ctx); -        GF_FREE(bdatt); -    } -    return 0; -} - -int -bd_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                int op_errno, gf_dirent_t *entries, dict_t *xdata) -{ -    gf_dirent_t *entry = NULL; -    uint64_t size = 0; -    char *type = NULL; - -    if (op_ret < 0) -        goto out; - -    list_for_each_entry(entry, &entries->list, list) -    { -        if (entry->d_type != DT_REG) -            continue; -        if (!bd_get_bd_info(frame, this, entry->dict, entry->d_stat.ia_gfid, -                            &type, &size)) { -            entry->d_stat.ia_size = size; -            entry->d_stat.ia_blocks = size / 512; -            GF_FREE(type); -        } -    } - -out: -    BD_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); -    return 0; -} - -/* - * bd_readdirp: In bd_readdirp_cbk if the file and BD_XATTR_SIZE is set - * ia_size is updated with the LV(BD_XATTR_SIZE) size - */ -int32_t -bd_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -            off_t off, dict_t *dict) -{ -    int op_errno = EINVAL; -    bd_local_t *local = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(this->private, out); - -    if (!dict) { -        local = bd_local_init(frame, this); -        BD_VALIDATE_MEM_ALLOC(local, op_errno, out); -        local->dict = dict_new(); -        BD_VALIDATE_MEM_ALLOC(local->dict, op_errno, out); -        dict = local->dict; -    } - -    if (dict_set_int8(dict, BD_XATTR, 0)) { -        gf_log(this->name, GF_LOG_WARNING, "failed to set key %s", BD_XATTR); -        goto out; -    } - -    STACK_WIND(frame, bd_readdirp_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->readdirp, fd, size, off, dict); - -    return 0; -out: -    BD_STACK_UNWIND(readdirp, frame, -1, op_errno, NULL, dict); -    return 0; -} - -int -bd_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -            int op_errno, struct iatt *buf, dict_t *xdata) -{ -    bd_local_t *local = frame->local; -    bd_attr_t *bdatt = NULL; - -    /* only regular files are part of BD object */ -    if (op_ret < 0 || buf->ia_type != IA_IFREG) -        goto out; - -    BD_VALIDATE_LOCAL_OR_GOTO(local, op_errno, out); - -    /* update buf with LV size */ -    if (!bd_inode_ctx_get(local->inode, this, &bdatt)) -        memcpy(buf, bdatt, sizeof(struct iatt)); - -out: -    BD_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata); -    return 0; -} - -int -bd_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    int op_errno = EINVAL; -    bd_local_t *local = NULL; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(loc, out); -    VALIDATE_OR_GOTO(loc->path, out); -    VALIDATE_OR_GOTO(this->private, out); - -    if (!bd_inode_ctx_get(loc->inode, this, &bdatt)) { -        BD_STACK_UNWIND(stat, frame, 0, 0, &bdatt->iatt, xdata); -        return 0; -    } - -    local = bd_local_init(frame, this); -    BD_VALIDATE_MEM_ALLOC(local, op_errno, out); -    local->inode = inode_ref(loc->inode); - -    STACK_WIND(frame, bd_stat_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->stat, loc, xdata); -    return 0; -out: -    BD_STACK_UNWIND(stat, frame, -1, op_errno, NULL, xdata); -    return 0; -} - -int -bd_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -              int op_errno, struct statvfs *buff, dict_t *xdata) -{ -    uint64_t size = 0; -    uint64_t fr_size = 0; -    bd_priv_t *priv = NULL; -    vg_t vg = NULL; - -    if (op_ret < 0) -        goto out; - -    priv = this->private; - -    vg = lvm_vg_open(priv->handle, priv->vg, "r", 0); -    if (!vg) { -        gf_log(this->name, GF_LOG_WARNING, "opening VG %s failed", priv->vg); -        op_ret = -1; -        op_errno = EAGAIN; -        goto out; -    } -    size = lvm_vg_get_size(vg); -    fr_size = lvm_vg_get_free_size(vg); -    lvm_vg_close(vg); - -    buff->f_blocks += size / buff->f_frsize; -    buff->f_bfree += fr_size / buff->f_frsize; -    buff->f_bavail += fr_size / buff->f_frsize; - -out: -    BD_STACK_UNWIND(statfs, frame, op_ret, op_errno, buff, xdata); -    return 0; -} - -/* - * bd_statfs: Mimics statfs by returning used/free extents in the VG - */ -int -bd_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) -{ -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(this->private, out); -    VALIDATE_OR_GOTO(loc, out); - -    STACK_WIND(frame, bd_statfs_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->statfs, loc, xdata); -    return 0; -out: -    BD_STACK_UNWIND(statfs, frame, -1, EINVAL, NULL, NULL); -    return 0; -} - -int -bd_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -             int op_errno, struct iatt *buf, dict_t *xdata) -{ -    bd_attr_t *bdatt = NULL; -    bd_local_t *local = frame->local; - -    /* only regular files are part of BD object */ -    if (op_ret < 0 || buf->ia_type != IA_IFREG) -        goto out; - -    BD_VALIDATE_LOCAL_OR_GOTO(local, op_errno, out); - -    /* update buf with LV size */ -    if (!bd_inode_ctx_get(local->inode, this, &bdatt)) -        memcpy(buf, &bdatt->iatt, sizeof(struct iatt)); - -out: -    BD_STACK_UNWIND(fstat, frame, op_ret, op_errno, buf, xdata); -    return 0; -} - -int -bd_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) -{ -    int op_errno = EINVAL; -    bd_local_t *local = NULL; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(this->private, out); - -    /* if its already cached return it */ -    if (!bd_inode_ctx_get(fd->inode, this, &bdatt)) { -        BD_STACK_UNWIND(fstat, frame, 0, 0, &bdatt->iatt, xdata); -        return 0; -    } - -    local = bd_local_init(frame, this); -    BD_VALIDATE_MEM_ALLOC(local, op_errno, out); - -    local->inode = inode_ref(fd->inode); - -    STACK_WIND(frame, bd_fstat_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fstat, fd, xdata); - -    return 0; -out: -    BD_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, xdata); -    return 0; -} - -/* - * bd_readv: If posix file, invokes posix_readv otherwise reads from the BD - * file - */ -int -bd_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -         off_t offset, uint32_t flags, dict_t *xdata) -{ -    int ret = -1; -    int _fd = -1; -    int32_t op_ret = -1; -    int32_t op_errno = 0; -    bd_fd_t *bd_fd = NULL; -    struct iovec vec = { -        0, -    }; -    struct iobuf *iobuf = NULL; -    struct iobref *iobref = NULL; -    uint64_t bd_size = 0; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(this->private, out); - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd) { -        STACK_WIND(frame, default_readv_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, -                   xdata); -        return 0; -    } -    if (!size) { -        op_errno = EINVAL; -        gf_log(this->name, GF_LOG_WARNING, "size=%" GF_PRI_SIZET, size); -        goto out; -    } -    iobuf = iobuf_get2(this->ctx->iobuf_pool, size); -    if (!iobuf) { -        op_errno = ENOMEM; -        goto out; -    } -    _fd = bd_fd->fd; -    op_ret = sys_pread(_fd, iobuf->ptr, size, offset); -    if (op_ret == -1) { -        op_errno = errno; -        gf_log(this->name, GF_LOG_ERROR, "read failed on fd=%p: %s", fd, -               strerror(op_errno)); -        goto out; -    } - -    vec.iov_base = iobuf->ptr; -    vec.iov_len = op_ret; - -    iobref = iobref_new(); -    iobref_add(iobref, iobuf); - -    if (bd_inode_ctx_get(fd->inode, this, &bdatt)) { -        op_errno = EINVAL; -        op_ret = -1; -        goto out; -    } -    bd_size = bdatt->iatt.ia_size; -    if (!bd_size || (offset + vec.iov_len) >= bd_size) -        op_errno = ENOENT; - -    op_ret = vec.iov_len; -    bd_update_amtime(&bdatt->iatt, GF_SET_ATTR_ATIME); - -out: -    BD_STACK_UNWIND(readv, frame, op_ret, op_errno, &vec, 1, &bdatt->iatt, -                    iobref, NULL); - -    if (iobref) -        iobref_unref(iobref); -    if (iobuf) -        iobuf_unref(iobuf); - -    return 0; -} - -#ifdef BLKDISCARD -/* - * bd_discard: Sends BLKDISCARD ioctl to the block device - */ -int -bd_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -           size_t len, dict_t *xdata) -{ -    int ret = -1; -    int op_errno = EINVAL; -    bd_fd_t *bd_fd = NULL; -    uint64_t param[2] = { -        0, -    }; -    bd_attr_t *bdatt = NULL; -    struct iatt prebuf = { -        0, -    }; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(this->private, out); -    VALIDATE_OR_GOTO(fd, out); - -    /* posix */ -    if (bd_inode_ctx_get(fd->inode, this, &bdatt)) { -        STACK_WIND(frame, default_discard_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); -        return 0; -    } - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd) { -        op_errno = EINVAL; -        goto out; -    } - -    param[0] = offset; -    param[1] = len; -    ret = ioctl(bd_fd->fd, BLKDISCARD, param); -    if (ret < 0) { -        if (errno == ENOTTY) -            op_errno = ENOSYS; -        else -            op_errno = errno; -        goto out; -    } -    memcpy(&prebuf, &bdatt->iatt, sizeof(prebuf)); -    bd_update_amtime(&bdatt->iatt, GF_SET_ATTR_MTIME); - -    BD_STACK_UNWIND(discard, frame, ret, op_errno, &prebuf, &bdatt->iatt, -                    xdata); -    return 0; - -out: -    BD_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} -#else - -int -bd_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -           size_t len, dict_t *xdata) -{ -    BD_STACK_UNWIND(discard, frame, -1, ENOSYS, NULL, NULL, NULL); -    return 0; -} -#endif - -/* - * Call back from posix_open for opening the backing posix file - * If it failed, close BD fd - */ -int -bd_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -            int op_errno, fd_t *fd, dict_t *xdata) -{ -    bd_fd_t *bd_fd = NULL; -    bd_attr_t *bdatt = NULL; - -    if (!op_ret) -        goto out; - -    bd_inode_ctx_get(fd->inode, this, &bdatt); -    if (!bdatt) /* posix file */ -        goto out; - -    /* posix open failed */ -    if (bd_fd_ctx_get(this, fd, &bd_fd) < 0) { -        gf_log(this->name, GF_LOG_WARNING, "bd_fd is NULL from fd=%p", fd); -        goto out; -    } -    sys_close(bd_fd->fd); -    GF_FREE(bd_fd); - -out: -    BD_STACK_UNWIND(open, frame, op_ret, op_errno, fd, NULL); - -    return 0; -} - -/* - * bd_open: Opens BD file if given posix file is mapped to BD. Also opens - * posix file. - * fd contains both posix and BD fd - */ -int32_t -bd_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -        fd_t *fd, dict_t *xdata) -{ -    int32_t ret = EINVAL; -    bd_fd_t *bd_fd = NULL; -    bd_attr_t *bdatt = NULL; -    bd_gfid_t gfid = { -        0, -    }; -    char *devpath = NULL; -    bd_priv_t *priv = this->private; -    int _fd = -1; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(this->private, out); -    VALIDATE_OR_GOTO(loc, out); -    VALIDATE_OR_GOTO(fd, out); - -    /* not bd file */ -    if (fd->inode->ia_type != IA_IFREG || -        bd_inode_ctx_get(fd->inode, this, &bdatt)) -        goto posix; - -    uuid_utoa_r(fd->inode->gfid, gfid); -    gf_asprintf(&devpath, "/dev/%s/%s", priv->vg, gfid); -    BD_VALIDATE_MEM_ALLOC(devpath, ret, out); - -    _fd = open(devpath, flags | O_LARGEFILE, 0); -    if (_fd < 0) { -        ret = errno; -        gf_log(this->name, GF_LOG_ERROR, "open on %s: %s", devpath, -               strerror(ret)); -        goto out; -    } -    bd_fd = GF_CALLOC(1, sizeof(bd_fd_t), gf_bd_fd); -    BD_VALIDATE_MEM_ALLOC(bd_fd, ret, out); - -    bd_fd->fd = _fd; -    bd_fd->flag = flags | O_LARGEFILE; - -    if (fd_ctx_set(fd, this, (uint64_t)(long)bd_fd) < 0) { -        gf_log(this->name, GF_LOG_WARNING, "failed to set the fd context fd=%p", -               fd); -        goto out; -    } - -    ret = 0; - -posix: - -    /* open posix equivalent of this file, fd needed for fd related -       operations like fsetxattr, ftruncate etc */ -    STACK_WIND(frame, bd_open_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); - -    GF_FREE(devpath); -    return 0; -out: -    BD_STACK_UNWIND(open, frame, -1, ret, fd, NULL); - -    GF_FREE(devpath); -    if (ret) { -        if (_fd >= 0) -            sys_close(_fd); -        GF_FREE(bd_fd); -    } - -    return 0; -} - -/* - * call back from posix_setattr after updating iatt to posix file. - */ -int -bd_fsync_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int op_ret, int op_errno, struct iatt *pre, -                     struct iatt *post, dict_t *xdata) -{ -    bd_local_t *local = frame->local; -    bd_attr_t *bdatt = local->bdatt; - -    BD_STACK_UNWIND(fsync, frame, op_ret, op_errno, &bdatt->iatt, &bdatt->iatt, -                    NULL); -    return 0; -} - -int -bd_do_fsync(int fd, int datasync) -{ -    int op_errno = 0; - -    if (datasync) { -        if (sys_fdatasync(fd)) { -            op_errno = errno; -            gf_log(THIS->name, GF_LOG_ERROR, "fdatasync on fd=%d failed: %s", -                   fd, strerror(errno)); -        } - -    } else - -    { -        if (sys_fsync(fd)) { -            op_errno = errno; -            gf_log(THIS->name, GF_LOG_ERROR, "fsync on fd=%d failed: %s", fd, -                   strerror(op_errno)); -        } -    } - -    return op_errno; -} - -/* - * bd_fsync: Syncs if BD fd, forwards the request to posix - * fsync -> posix_setattr -> posix_fsync - */ -int32_t -bd_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, -         dict_t *xdata) -{ -    int ret = -1; -    int32_t op_ret = -1; -    int32_t op_errno = 0; -    bd_fd_t *bd_fd = NULL; -    bd_attr_t *bdatt = NULL; -    bd_local_t *local = NULL; -    int valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME; -    struct iatt prebuf = { -        0, -    }; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(this->private, out); - -    ret = bd_inode_ctx_get(fd->inode, this, &bdatt); -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd || !bdatt) { -        STACK_WIND(frame, default_fsync_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata); -        return 0; -    } - -    memcpy(&prebuf, &bdatt->iatt, sizeof(struct iatt)); - -    op_errno = bd_do_fsync(bd_fd->fd, datasync); -    if (op_errno) -        goto out; - -    /* For BD, Update the a|mtime during full fsync only */ -    if (!datasync) { -        local = bd_local_init(frame, this); -        /* In case of mem failure, should posix flush called ? */ -        BD_VALIDATE_MEM_ALLOC(local, op_errno, out); - -        local->bdatt = GF_CALLOC(1, sizeof(bd_attr_t), gf_bd_attr); -        BD_VALIDATE_MEM_ALLOC(local->bdatt, op_errno, out); - -        local->bdatt->type = gf_strdup(bdatt->type); -        memcpy(&local->bdatt->iatt, &bdatt->iatt, sizeof(struct iatt)); -        bd_update_amtime(&local->bdatt->iatt, valid); -        gf_uuid_copy(local->loc.gfid, fd->inode->gfid); -        STACK_WIND(frame, bd_fsync_setattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setattr, &local->loc, -                   &local->bdatt->iatt, valid, NULL); -        return 0; -    } - -out: -    BD_STACK_UNWIND(fsync, frame, op_ret, op_errno, &prebuf, &bdatt->iatt, -                    NULL); -    return 0; -} - -int -bd_flush_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int op_ret, int op_errno, struct iatt *pre, -                     struct iatt *post, dict_t *xdata) -{ -    BD_STACK_UNWIND(flush, frame, op_ret, op_errno, xdata); -    return 0; -} - -int -bd_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) -{ -    int ret = -1; -    bd_fd_t *bd_fd = NULL; -    bd_attr_t *bdatt = NULL; -    int valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME; -    bd_local_t *local = NULL; -    loc_t loc = { -        0, -    }; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(this->private, out); - -    ret = bd_inode_ctx_get(fd->inode, this, &bdatt); -    if (!bdatt) -        goto out; - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd || !bdatt) { -        gf_log(this->name, GF_LOG_WARNING, "bdfd/bdatt is NULL from fd=%p", fd); -        goto out; -    } - -    local = bd_local_init(frame, this); -    if (!local) { -        gf_log(this->name, GF_LOG_ERROR, "out of memory"); -        goto out; -    } - -    local->fd = fd_ref(fd); -    gf_uuid_copy(loc.gfid, bdatt->iatt.ia_gfid); - -    /* Update the a|mtime during flush */ -    STACK_WIND(frame, bd_flush_setattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->setattr, &loc, &bdatt->iatt, valid, -               NULL); - -    return 0; - -out: -    STACK_WIND(frame, default_flush_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->flush, fd, xdata); - -    return 0; -} - -int32_t -bd_release(xlator_t *this, fd_t *fd) -{ -    int ret = -1; -    bd_fd_t *bd_fd = NULL; -    uint64_t tmp_bfd = 0; -    bd_attr_t *bdatt = NULL; -    bd_priv_t *priv = this->private; - -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(priv, out); - -    ret = bd_inode_ctx_get(fd->inode, this, &bdatt); -    if (ret || !bdatt) /* posix file */ -        goto out; - -    /* FIXME: Update amtime during release */ - -    ret = fd_ctx_del(fd, this, &tmp_bfd); -    if (ret < 0) { -        gf_log(this->name, GF_LOG_WARNING, "bfd is NULL from fd=%p", fd); -        goto out; -    } -    bd_fd = (bd_fd_t *)(long)tmp_bfd; - -    sys_close(bd_fd->fd); -    GF_FREE(bd_fd); -out: -    return 0; -} - -/* - * Call back for removexattr after removing BD_XATTR in case of - * bd create failure - */ -int -bd_setx_rm_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int op_ret, int op_errno, dict_t *xdata) -{ -    bd_local_t *local = frame->local; - -    if (local->fd) -        BD_STACK_UNWIND(setxattr, frame, -1, EIO, xdata); -    else -        BD_STACK_UNWIND(setxattr, frame, -1, EIO, xdata); -    return 0; -} - -/* - * Call back after setting BD_XATTR. Creates BD. If BD creation is a failure - * invokes posix_removexattr to remove created BD_XATTR - */ -int -bd_setx_setx_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                 int op_errno, dict_t *xdata) -{ -    bd_local_t *local = frame->local; -    bd_attr_t *bdatt = NULL; - -    if (op_ret < 0) -        goto next; - -    /* Create LV */ -    op_errno = bd_create(local->inode->gfid, local->bdatt->iatt.ia_size, -                         local->bdatt->type, this->private); -    if (!op_errno) -        goto out; - -    /* LV creation failed, remove BD_XATTR */ -    if (local->fd) -        STACK_WIND(frame, bd_setx_rm_xattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fremovexattr, local->fd, BD_XATTR, -                   NULL); -    else -        STACK_WIND(frame, bd_setx_rm_xattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->removexattr, &local->loc, BD_XATTR, -                   NULL); - -    return 0; -out: - -    bdatt = GF_CALLOC(1, sizeof(bd_attr_t), gf_bd_attr); -    if (!bdatt) { -        op_ret = -1; -        op_errno = ENOMEM; -        goto next; -    } - -    memcpy(&bdatt->iatt, &local->bdatt->iatt, sizeof(struct iatt)); -    bdatt->type = gf_strdup(local->bdatt->type); - -    bd_inode_ctx_set(local->inode, THIS, bdatt); - -next: -    if (local->fd) -        BD_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); -    else -        BD_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); -    return 0; -} - -/* - * Call back from posix_stat - */ -int -bd_setx_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                 int op_errno, struct iatt *iatt, dict_t *xdata) -{ -    char *param = NULL; -    char *type = NULL; -    char *s_size = NULL; -    char *p = NULL; -    char *copy = NULL; -    bd_local_t *local = frame->local; -    bd_priv_t *priv = this->private; -    char *bd = NULL; -    uint64_t size = 0; - -    if (op_ret < 0) -        goto out; - -    if (!IA_ISREG(iatt->ia_type)) { -        op_errno = EOPNOTSUPP; -        goto out; -    } - -    param = copy = GF_MALLOC(local->data->len + 1, gf_common_mt_char); -    BD_VALIDATE_MEM_ALLOC(param, op_errno, out); - -    strncpy(param, local->data->data, local->data->len); -    param[local->data->len] = '\0'; - -    type = strtok_r(param, ":", &p); -    if (!type) { -        op_errno = EINVAL; -        goto out; -    } - -    if (strcmp(type, BD_LV) && strcmp(type, BD_THIN)) { -        gf_log(this->name, GF_LOG_WARNING, "Invalid bd type %s given", type); -        op_errno = EINVAL; -        goto out; -    } - -    if (!strcmp(type, BD_THIN) && !(priv->caps & BD_CAPS_THIN)) { -        gf_log(this->name, GF_LOG_WARNING, -               "THIN lv not supported by " -               "this volume"); -        op_errno = EOPNOTSUPP; -        goto out; -    } - -    s_size = strtok_r(NULL, ":", &p); - -    /* If size not specified get default size */ -    if (!s_size) -        size = bd_get_default_extent(priv); -    else -        gf_string2bytesize_uint64(s_size, &size); - -    gf_asprintf(&bd, "%s:%ld", type, size); -    BD_VALIDATE_MEM_ALLOC(bd, op_errno, out); - -    local->dict = dict_new(); -    BD_VALIDATE_MEM_ALLOC(local->dict, op_errno, out); - -    local->bdatt = GF_CALLOC(1, sizeof(bd_attr_t), gf_bd_attr); -    BD_VALIDATE_MEM_ALLOC(local->bdatt, op_errno, out); - -    if (dict_set_dynstr(local->dict, BD_XATTR, bd) < 0) { -        op_errno = EINVAL; -        goto out; -    } - -    local->bdatt->type = gf_strdup(type); -    memcpy(&local->bdatt->iatt, iatt, sizeof(struct iatt)); -    local->bdatt->iatt.ia_size = size; - -    if (local->fd) -        STACK_WIND(frame, bd_setx_setx_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fsetxattr, local->fd, local->dict, -                   0, NULL); -    else -        STACK_WIND(frame, bd_setx_setx_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setxattr, &local->loc, local->dict, -                   0, NULL); - -    if (copy) -        GF_FREE(copy); -    return 0; - -out: -    if (local->fd) -        BD_STACK_UNWIND(fsetxattr, frame, -1, op_errno, xdata); -    else -        BD_STACK_UNWIND(setxattr, frame, -1, op_errno, xdata); - -    GF_FREE(bd); -    GF_FREE(copy); -    return 0; -} - -int -bd_offload_rm_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                        int op_ret, int op_errno, dict_t *xdata) -{ -    bd_local_t *local = frame->local; - -    if (local->fd) -        BD_STACK_UNWIND(fsetxattr, frame, -1, EIO, NULL); -    else -        BD_STACK_UNWIND(setxattr, frame, -1, EIO, NULL); - -    return 0; -} - -int -bd_offload_setx_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int op_ret, int op_errno, dict_t *xdata) -{ -    bd_local_t *local = frame->local; - -    if (op_ret < 0) -        goto out; - -    if (local->offload == BD_OF_SNAPSHOT) -        op_ret = bd_snapshot_create(frame->local, this->private); -    else -        op_ret = bd_clone(frame->local, this->private); - -    if (op_ret) { -        STACK_WIND(frame, bd_offload_rm_xattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->removexattr, local->dloc, BD_XATTR, -                   NULL); -        return 0; -    } - -out: -    if (local->fd) -        BD_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, NULL); -    else -        BD_STACK_UNWIND(setxattr, frame, op_ret, op_errno, NULL); - -    return 0; -} - -int -bd_offload_getx_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) -{ -    char *bd = NULL; -    bd_local_t *local = frame->local; -    char *type = NULL; -    char *p = NULL; - -    if (op_ret < 0) -        goto out; - -    if (dict_get_str(xattr, BD_XATTR, &p)) { -        op_errno = EINVAL; -        goto out; -    } - -    type = gf_strdup(p); -    BD_VALIDATE_MEM_ALLOC(type, op_errno, out); - -    p = strrchr(type, ':'); -    if (!p) { -        op_errno = EINVAL; -        gf_log(this->name, GF_LOG_WARNING, "source file xattr %s corrupted?", -               type); -        goto out; -    } - -    *p = '\0'; - -    /* For clone size is taken from source LV */ -    if (!local->size) { -        p++; -        gf_string2bytesize_uint64(p, &local->size); -    } -    gf_asprintf(&bd, "%s:%ld", type, local->size); -    local->bdatt->type = gf_strdup(type); -    dict_del(local->dict, LINKTO); -    if (dict_set_dynstr(local->dict, BD_XATTR, bd)) { -        op_errno = EINVAL; -        goto out; -    } - -    STACK_WIND(frame, bd_offload_setx_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->setxattr, local->dloc, local->dict, 0, -               NULL); - -    if (type) -        GF_FREE(type); -    return 0; - -out: -    if (local->fd) -        BD_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); -    else -        BD_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); - -    GF_FREE(type); -    GF_FREE(bd); - -    return 0; -} - -int -bd_offload_dest_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                           int op_ret, int op_errno, inode_t *inode, -                           struct iatt *iatt, dict_t *xattr, -                           struct iatt *postparent) -{ -    bd_local_t *local = frame->local; -    char *bd = NULL; -    char *linkto = NULL; -    int ret = -1; - -    if (op_ret < 0 && op_errno != ENODATA) { -        op_errno = EINVAL; -        goto out; -    } - -    if (!IA_ISREG(iatt->ia_type)) { -        op_errno = EINVAL; -        gf_log(this->name, GF_LOG_WARNING, -               "destination gfid is not a " -               "regular file"); -        goto out; -    } - -    ret = dict_get_str(xattr, LINKTO, &linkto); -    if (linkto) { -        op_errno = EINVAL; -        gf_log(this->name, GF_LOG_WARNING, -               "destination file not " -               "present in same brick"); -        goto out; -    } - -    ret = dict_get_str(xattr, BD_XATTR, &bd); -    if (bd) { -        op_errno = EEXIST; -        goto out; -    } - -    local->bdatt = GF_CALLOC(1, sizeof(bd_attr_t), gf_bd_attr); -    BD_VALIDATE_MEM_ALLOC(local->bdatt, op_errno, out); - -    STACK_WIND(frame, bd_offload_getx_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->getxattr, &local->loc, BD_XATTR, NULL); - -    return 0; -out: -    if (local->fd) -        BD_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); -    else -        BD_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); - -    return (ret == 0) ? 0 : ret; -} - -int -bd_merge_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                    int op_ret, int op_errno, struct iatt *preparent, -                    struct iatt *postparent, dict_t *xdata) -{ -    /* FIXME: if delete failed, remove xattr */ - -    BD_STACK_UNWIND(setxattr, frame, op_ret, op_errno, NULL); -    return 0; -} - -int -bd_do_merge(call_frame_t *frame, xlator_t *this) -{ -    bd_local_t *local = frame->local; -    inode_t *parent = NULL; -    char *p = NULL; -    int op_errno = 0; - -    op_errno = bd_merge(this->private, local->inode->gfid); -    if (op_errno) -        goto out; - -    /* -     * posix_unlink needs loc->pargfid to be valid, but setxattr FOP does -     * not have loc->pargfid set. Get parent's gfid by getting parents inode -     */ -    parent = inode_parent(local->inode, NULL, NULL); -    if (!parent) { -        /* -         * FIXME: Snapshot LV already deleted. -         * remove xattr, instead of returning failure -         */ -        op_errno = EINVAL; -        goto out; -    } -    gf_uuid_copy(local->loc.pargfid, parent->gfid); - -    p = strrchr(local->loc.path, '/'); -    if (p) -        p++; -    local->loc.name = p; - -    STACK_WIND(frame, bd_merge_unlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->unlink, &local->loc, 0, NULL); - -    return 0; -out: -    BD_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); - -    return op_errno; -} - -int -bd_offload(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, -           bd_offload_t offload) -{ -    char *param = NULL; -    char *param_copy = NULL; -    char *p = NULL; -    char *size = NULL; -    char *gfid = NULL; -    int op_errno = 0; -    bd_local_t *local = frame->local; - -    param = GF_MALLOC(local->data->len + 1, gf_common_mt_char); -    BD_VALIDATE_MEM_ALLOC(param, op_errno, out); -    param_copy = param; - -    local->dict = dict_new(); -    BD_VALIDATE_MEM_ALLOC(local->dict, op_errno, out); - -    local->dloc = GF_CALLOC(1, sizeof(loc_t), gf_bd_loc_t); -    BD_VALIDATE_MEM_ALLOC(local->dloc, op_errno, out); - -    strncpy(param, local->data->data, local->data->len); -    param[local->data->len] = '\0'; - -    gfid = strtok_r(param, ":", &p); -    size = strtok_r(NULL, ":", &p); -    if (size) -        gf_string2bytesize_uint64(size, &local->size); -    else if (offload != BD_OF_CLONE) -        local->size = bd_get_default_extent(this->private); - -    if (dict_set_int8(local->dict, BD_XATTR, 1) < 0) { -        op_errno = EINVAL; -        goto out; -    } -    if (dict_set_int8(local->dict, LINKTO, 1) < 0) { -        op_errno = EINVAL; -        goto out; -    } - -    gf_uuid_parse(gfid, local->dloc->gfid); -    local->offload = offload; - -    STACK_WIND(frame, bd_offload_dest_lookup_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lookup, local->dloc, local->dict); - -    if (param_copy) -        GF_FREE(param_copy); -    return 0; - -out: -    if (fd) -        BD_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); -    else -        BD_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); - -    GF_FREE(param_copy); -    return 0; -} - -/* - * bd_setxattr: Used to create & map an LV to a posix file using - * BD_XATTR xattr - * bd_setxattr -> posix_stat -> bd_setx_stat_cbk -> posix_setxattr -> - * bd_setx_setx_cbk -> create_lv - * if create_lv failed, posix_removexattr -> bd_setx_rm_xattr_cbk - */ -int -bd_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, -            int flags, dict_t *xdata) -{ -    int op_errno = 0; -    data_t *data = NULL; -    bd_local_t *local = NULL; -    bd_attr_t *bdatt = NULL; -    bd_offload_t cl_type = BD_OF_NONE; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); - -    if ((data = dict_get(dict, BD_XATTR))) -        cl_type = BD_OF_NONE; -    else if ((data = dict_get(dict, BD_CLONE))) -        cl_type = BD_OF_CLONE; -    else if ((data = dict_get(dict, BD_SNAPSHOT))) -        cl_type = BD_OF_SNAPSHOT; -    else if ((data = dict_get(dict, BD_MERGE))) -        cl_type = BD_OF_MERGE; - -    bd_inode_ctx_get(loc->inode, this, &bdatt); -    if (!cl_type && !data) { -        STACK_WIND(frame, default_setxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); -        return 0; -    } - -    local = bd_local_init(frame, this); -    BD_VALIDATE_MEM_ALLOC(local, op_errno, out); - -    local->data = data; -    loc_copy(&local->loc, loc); -    local->inode = inode_ref(loc->inode); - -    if (cl_type) { -        /* For cloning/snapshot, source file must be mapped to LV */ -        if (!bdatt) { -            gf_log(this->name, GF_LOG_WARNING, "%s not mapped to BD", -                   loc->path); -            op_errno = EINVAL; -            goto out; -        } -        if (cl_type == BD_OF_MERGE) -            bd_do_merge(frame, this); -        else -            bd_offload(frame, this, loc, NULL, cl_type); -    } else if (data) { -        if (bdatt) { -            gf_log(this->name, GF_LOG_WARNING, "%s already mapped to BD", -                   loc->path); -            op_errno = EEXIST; -            goto out; -        } -        STACK_WIND(frame, bd_setx_stat_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->stat, loc, xdata); -    } - -    return 0; -out: -    if (op_errno) -        STACK_UNWIND_STRICT(setxattr, frame, -1, op_errno, xdata); - -    return 0; -} - -/* - * bd_fsetxattr: Used to create/map an LV to a posix file using - * BD_XATTR xattr - * bd_fsetxattr ->  posix_fstat -> bd_setx_stat_cbk -> posix_fsetxattr -> - * bd_setx_setx_cbk -> create_lv - * if create_lv failed, posix_removexattr -> bd_setx_rm_xattr_cbk - * -> bd_fsetxattr_cbk - */ -int32_t -bd_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, -             int flags, dict_t *xdata) -{ -    int op_errno = 0; -    data_t *data = NULL; -    bd_attr_t *bdatt = NULL; -    bd_local_t *local = NULL; -    bd_offload_t cl_type = BD_OF_NONE; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(this->private, out); -    VALIDATE_OR_GOTO(fd, out); - -    bd_inode_ctx_get(fd->inode, this, &bdatt); - -    if ((data = dict_get(dict, BD_XATTR))) -        cl_type = BD_OF_NONE; -    else if ((data = dict_get(dict, BD_CLONE))) -        cl_type = BD_OF_CLONE; -    else if ((data = dict_get(dict, BD_SNAPSHOT))) -        cl_type = BD_OF_SNAPSHOT; -    else if ((data = dict_get(dict, BD_MERGE))) { -        /* -         * bd_merge is not supported for fsetxattr, because snapshot LV -         * is opened and it causes problem in snapshot merge -         */ -        op_errno = EOPNOTSUPP; -        goto out; -    } - -    bd_inode_ctx_get(fd->inode, this, &bdatt); - -    if (!cl_type && !data) { -        /* non bd file object */ -        STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); -        return 0; -    } - -    local = bd_local_init(frame, this); -    BD_VALIDATE_MEM_ALLOC(local, op_errno, out); - -    local->inode = inode_ref(fd->inode); -    local->fd = fd_ref(fd); -    local->data = data; - -    if (cl_type) { -        /* For cloning/snapshot, source file must be mapped to LV */ -        if (!bdatt) { -            gf_log(this->name, GF_LOG_WARNING, "fd %p not mapped to BD", fd); -            op_errno = EINVAL; -            goto out; -        } -        bd_offload(frame, this, NULL, fd, cl_type); -    } else if (data) { -        if (bdatt) { -            gf_log(this->name, GF_LOG_WARNING, "fd %p already mapped to BD", -                   fd); -            op_errno = EEXIST; -            goto out; -        } -        STACK_WIND(frame, bd_setx_stat_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fstat, fd, xdata); -    } - -    return 0; -out: - -    BD_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); - -    return 0; -} - -int32_t -bd_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, -               const char *name, dict_t *xdata) -{ -    if (!strcmp(name, BD_XATTR)) -        goto out; - -    STACK_WIND(frame, default_removexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); -    return 0; -out: -    BD_STACK_UNWIND(removexattr, frame, -1, ENODATA, NULL); -    return 0; -} - -int32_t -bd_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, -                dict_t *xdata) -{ -    if (!strcmp(name, BD_XATTR)) -        goto out; - -    STACK_WIND(frame, default_removexattr_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); - -    return 0; -out: -    BD_STACK_UNWIND(fremovexattr, frame, -1, ENODATA, NULL); -    return 0; -} - -int -bd_trunc_setxattr_setx_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                           int op_ret, int op_errno, dict_t *xdata) -{ -    bd_local_t *local = frame->local; - -    if (local->fd) -        BD_STACK_UNWIND(ftruncate, frame, -1, EIO, NULL, NULL, NULL); -    else -        BD_STACK_UNWIND(truncate, frame, -1, EIO, NULL, NULL, NULL); - -    return 0; -} - -/* - * Call back for setxattr after setting BD_XATTR_SIZE. - */ -int -bd_trunc_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                      int op_ret, int op_errno, dict_t *xdata) -{ -    bd_local_t *local = frame->local; -    bd_attr_t *bdatt = NULL; -    struct iatt prebuf = { -        0, -    }; -    char *bd = NULL; - -    if (op_ret < 0) -        goto out; - -    bd_inode_ctx_get(local->inode, this, &bdatt); -    if (!bdatt) -        goto revert_xattr; - -    op_errno = bd_resize(this->private, local->inode->gfid, -                         local->bdatt->iatt.ia_size); -    if (op_errno) -        goto revert_xattr; - -    memcpy(&prebuf, &bdatt->iatt, sizeof(struct iatt)); -    /* LV resized, update new size in the cache */ -    bdatt->iatt.ia_size = local->bdatt->iatt.ia_size; - -    if (local->fd) -        BD_STACK_UNWIND(ftruncate, frame, 0, 0, &prebuf, &bdatt->iatt, NULL); -    else -        BD_STACK_UNWIND(truncate, frame, 0, 0, &prebuf, &bdatt->iatt, NULL); - -    return 0; - -revert_xattr: -    /* revert setxattr */ -    op_ret = dict_get_str(local->dict, BD_XATTR, &bd); -    GF_FREE(bd); -    bd = NULL; -    if (bdatt) -        gf_asprintf(&bd, "%s:%ld", bdatt->type, bdatt->iatt.ia_size); - -    if (local->fd) -        STACK_WIND(frame, bd_trunc_setxattr_setx_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fsetxattr, local->fd, local->dict, -                   0, NULL); -    else -        STACK_WIND(frame, bd_trunc_setxattr_setx_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setxattr, &local->loc, local->dict, -                   0, NULL); - -    if (bd) -        GF_FREE(bd); -    return 0; -out: -    if (local->fd) -        BD_STACK_UNWIND(ftruncate, frame, -1, EIO, NULL, NULL, NULL); -    else -        BD_STACK_UNWIND(truncate, frame, -1, EIO, NULL, NULL, NULL); - -    return 0; -} - -/* - * call back from posix_[f]truncate_stat - * If offset > LV size, it resizes the LV and calls posix_setxattr - * to update new LV size in xattr else calls posix_setattr for updating - * the posix file so that truncate fop behaves properly - */ -int -bd_trunc_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                  int op_errno, struct iatt *buf, dict_t *xdata) -{ -    char *bd = NULL; -    bd_local_t *local = frame->local; -    bd_attr_t *bdatt = NULL; - -    if (op_ret < 0) -        goto out; - -    local->dict = dict_new(); -    BD_VALIDATE_MEM_ALLOC(local->dict, op_errno, out); - -    bd_inode_ctx_get(local->inode, this, &bdatt); -    if (!bdatt) { -        op_errno = EINVAL; -        goto out; -    } - -    gf_asprintf(&bd, "%s:%ld", bdatt->type, local->bdatt->iatt.ia_size); -    if (dict_set_dynstr(local->dict, BD_XATTR, bd)) { -        op_errno = EINVAL; -        goto out; -    } - -    if (local->fd) -        STACK_WIND(frame, bd_trunc_setxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fsetxattr, local->fd, local->dict, -                   0, NULL); -    else -        STACK_WIND(frame, bd_trunc_setxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setxattr, &local->loc, local->dict, -                   0, NULL); - -    return 0; -out: -    if (local->fd) -        BD_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); -    else -        BD_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); -    GF_FREE(bd); -    return 0; -} - -void -bd_do_trunc(call_frame_t *frame, xlator_t *this, fd_t *fd, loc_t *loc, -            off_t offset, bd_attr_t *bdatt) -{ -    bd_local_t *local = NULL; -    struct iatt prebuf = { -        0, -    }; -    int op_errno = 0; -    int op_ret = -1; - -    /* If requested size is less than LV size, return success */ -    if (offset <= bdatt->iatt.ia_size) { -        memcpy(&prebuf, &bdatt->iatt, sizeof(struct iatt)); -        bd_update_amtime(&bdatt->iatt, GF_SET_ATTR_MTIME); -        op_ret = 0; -        goto out; -    } - -    local = bd_local_init(frame, this); -    BD_VALIDATE_MEM_ALLOC(local, op_errno, out); - -    local->bdatt = GF_CALLOC(1, sizeof(bd_attr_t), gf_bd_attr); -    BD_VALIDATE_MEM_ALLOC(local->bdatt, op_errno, out); - -    if (fd) { -        local->inode = inode_ref(fd->inode); -        local->fd = fd_ref(fd); -    } else { -        local->inode = inode_ref(loc->inode); -        loc_copy(&local->loc, loc); -    } - -    local->bdatt->iatt.ia_size = bd_adjust_size(this->private, offset); - -    STACK_WIND(frame, bd_trunc_stat_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->fstat, fd, NULL); - -    return; - -out: -    if (fd) -        BD_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, &prebuf, -                        &bdatt->iatt, NULL); -    else -        BD_STACK_UNWIND(truncate, frame, op_ret, op_errno, &prebuf, -                        &bdatt->iatt, NULL); -    return; -} - -/* - * bd_ftruncate: Resizes a LV if fd belongs to BD. - */ -int32_t -bd_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -             dict_t *xdata) -{ -    int op_errno = 0; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); - -    if (bd_inode_ctx_get(fd->inode, this, &bdatt)) { -        STACK_WIND(frame, default_ftruncate_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); -        return 0; -    } - -    bd_do_trunc(frame, this, fd, NULL, offset, bdatt); -    return 0; -out: -    BD_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -/* - * bd_truncate: Resizes a LV if file maps to LV. - */ -int32_t -bd_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, -            dict_t *xdata) -{ -    int op_errno = 0; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(loc, out); - -    if (bd_inode_ctx_get(loc->inode, this, &bdatt)) { -        STACK_WIND(frame, default_truncate_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); -        return 0; -    } - -    bd_do_trunc(frame, this, NULL, loc, offset, bdatt); -    return 0; - -out: -    BD_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -__bd_pwritev(int fd, struct iovec *vector, int count, off_t offset, -             uint64_t bd_size) -{ -    int index = 0; -    int retval = 0; - -    if (!vector) -        return -EFAULT; - -    retval = sys_pwritev(fd, vector, count, offset); -    if (retval == -1) { -        int64_t off = offset; -        gf_log(THIS->name, GF_LOG_WARNING, -               "base %p, length %zd, offset %" PRId64 ", message %s", -               vector[index].iov_base, vector[index].iov_len, off, -               strerror(errno)); -        retval = -errno; -        goto err; -    } -/* - - -        internal_offset = offset; -        for (index = 0; index < count; index++) { -                if (internal_offset > bd_size) { -                        op_ret = -ENOSPC; -                        goto err; -                } -                if (internal_offset + vector[index].iov_len > bd_size) { -                        vector[index].iov_len = bd_size - internal_offset; -                        no_space = 1; -                } -                retval = sys_pwritev (fd, vector[index].iov_base, -                                      vector[index].iov_len, internal_offset); -                if (retval == -1) { -                        gf_log (THIS->name, GF_LOG_WARNING, -                                "base %p, length %ld, offset %ld, message %s", -                                vector[index].iov_base, vector[index].iov_len, -                                internal_offset, strerror (errno)); -                        op_ret = -errno; -                        goto err; -                } -                op_ret += retval; -                internal_offset += retval; -                if (no_space) -                        break; -        } -*/ -err: -    return retval; -} - -/* - * bd_writev: Writes to LV if its BD file or forwards the request to posix_write - * bd_writev -> posix_writev -> bd_writev_cbk - */ -int -bd_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, -          int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, -          dict_t *xdict) -{ -    int32_t op_ret = -1; -    int32_t op_errno = 0; -    int _fd = -1; -    bd_fd_t *bd_fd = NULL; -    int ret = -1; -    uint64_t size = 0; -    struct iatt prebuf = { -        0, -    }; -    bd_attr_t *bdatt = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); -    VALIDATE_OR_GOTO(vector, out); - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd) { /* posix fd */ -        STACK_WIND(frame, default_writev_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, -                   flags, iobref, xdict); -        return 0; -    } - -    _fd = bd_fd->fd; - -    if (bd_inode_ctx_get(fd->inode, this, &bdatt)) { -        op_ret = -1; -        op_errno = EINVAL; -        goto out; -    } -    size = bdatt->iatt.ia_size; - -    op_ret = __bd_pwritev(_fd, vector, count, offset, size); -    if (op_ret < 0) { -        op_errno = -op_ret; -        op_ret = -1; -        gf_log(this->name, GF_LOG_ERROR, "write failed: offset %" PRIu64 ", %s", -               offset, strerror(op_errno)); -        goto out; -    } - -    memcpy(&prebuf, &bdatt->iatt, sizeof(struct iatt)); -    bd_update_amtime(&bdatt->iatt, GF_SET_ATTR_MTIME); -out: - -    BD_STACK_UNWIND(writev, frame, op_ret, op_errno, &prebuf, &bdatt->iatt, -                    NULL); -    return 0; -} - -int -bd_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -               int op_errno, struct iatt *prebuf, struct iatt *postbuf, -               dict_t *xdata) -{ -    bd_attr_t *bdatt = NULL; -    int *valid = cookie; -    bd_local_t *local = frame->local; - -    if (op_ret < 0 || !valid || !local) -        goto out; - -    if (bd_inode_ctx_get(local->inode, this, &bdatt)) -        goto out; - -    if (*valid & GF_SET_ATTR_UID) -        bdatt->iatt.ia_uid = postbuf->ia_uid; -    else if (*valid & GF_SET_ATTR_GID) -        bdatt->iatt.ia_gid = postbuf->ia_gid; -    else if (*valid & GF_SET_ATTR_MODE) { -        bdatt->iatt.ia_type = postbuf->ia_type; -        bdatt->iatt.ia_prot = postbuf->ia_prot; -    } else if (*valid & GF_SET_ATTR_ATIME) { -        bdatt->iatt.ia_atime = postbuf->ia_atime; -        bdatt->iatt.ia_atime_nsec = postbuf->ia_atime_nsec; -    } else if (*valid & GF_SET_ATTR_MTIME) { -        bdatt->iatt.ia_mtime = postbuf->ia_mtime; -        bdatt->iatt.ia_mtime_nsec = postbuf->ia_mtime_nsec; -    } - -    bdatt->iatt.ia_ctime = postbuf->ia_ctime; -    bdatt->iatt.ia_ctime_nsec = postbuf->ia_ctime_nsec; - -    memcpy(postbuf, &bdatt->iatt, sizeof(struct iatt)); -out: -    GF_FREE(valid); -    BD_STACK_UNWIND(setattr, frame, op_ret, op_errno, prebuf, postbuf, xdata); -    return 0; -} - -int -bd_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, -           int32_t valid, dict_t *xdata) -{ -    bd_local_t *local = NULL; -    bd_attr_t *bdatt = NULL; -    int *ck_valid = NULL; - -    if (bd_inode_ctx_get(loc->inode, this, &bdatt)) { -        STACK_WIND(frame, default_setattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); -        return 0; -    } - -    local = bd_local_init(frame, this); -    if (!local) { -        gf_log(this->name, GF_LOG_ERROR, "out of memory"); -        goto out; -    } - -    ck_valid = GF_CALLOC(1, sizeof(valid), gf_bd_int32_t); -    if (!ck_valid) { -        gf_log(this->name, GF_LOG_ERROR, "out of memory"); -        goto out; -    } - -    local->inode = inode_ref(loc->inode); -    *ck_valid = valid; - -    STACK_WIND_COOKIE(frame, bd_setattr_cbk, ck_valid, FIRST_CHILD(this), -                      FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, -                      xdata); -    GF_FREE(ck_valid); -    return 0; -out: -    BD_STACK_UNWIND(setattr, frame, -1, ENOMEM, NULL, NULL, xdata); -    return 0; -} - -int -bd_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -            int op_errno, inode_t *inode, struct iatt *buf, -            struct iatt *preparent, struct iatt *postparent, dict_t *xdata) -{ -    bd_attr_t *bdatt = NULL; - -    if (op_ret < 0) -        goto out; - -    if (bd_inode_ctx_get(inode, this, &bdatt)) -        goto out; - -    bdatt->iatt.ia_ctime = buf->ia_ctime; -    bdatt->iatt.ia_ctime_nsec = buf->ia_ctime_nsec; -    bdatt->iatt.ia_nlink = buf->ia_nlink; -    memcpy(buf, &bdatt->iatt, sizeof(struct iatt)); - -out: -    BD_STACK_UNWIND(link, frame, op_ret, op_errno, inode, buf, preparent, -                    postparent, NULL); -    return 0; -} - -int -bd_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, -        dict_t *xdata) -{ -    STACK_WIND(frame, bd_link_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); -    return 0; -} - -int -bd_handle_special_xattrs(call_frame_t *frame, xlator_t *this, loc_t *loc, -                         fd_t *fd, const char *name, dict_t *xdata) -{ -    dict_t *xattr = NULL; -    int op_ret = -1; -    int op_errno = ENOMEM; -    ; -    bd_priv_t *priv = this->private; - -    xattr = dict_new(); -    if (!xattr) -        goto out; - -    if (!strcmp(name, VOL_TYPE)) -        op_ret = dict_set_int64(xattr, (char *)name, 1); -    else if (!strcmp(name, VOL_CAPS)) -        op_ret = dict_set_int64(xattr, (char *)name, priv->caps); -    else -        op_ret = bd_get_origin(this->private, loc, fd, xattr); - -out: -    if (loc) -        BD_STACK_UNWIND(getxattr, frame, op_ret, op_errno, xattr, xdata); -    else -        BD_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, xattr, xdata); - -    op_ret = dict_reset(xattr); -    dict_unref(xattr); - -    return 0; -} - -int -bd_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, -             dict_t *xdata) -{ -    if (name && (!strcmp(name, VOL_TYPE) || !strcmp(name, VOL_CAPS) || -                 !strcmp(name, BD_ORIGIN))) -        bd_handle_special_xattrs(frame, this, NULL, fd, name, xdata); -    else -        STACK_WIND(frame, default_fgetxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); -    return 0; -} - -int -bd_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, -            dict_t *xdata) -{ -    if (name && (!strcmp(name, VOL_TYPE) || !strcmp(name, VOL_CAPS) || -                 !strcmp(name, BD_ORIGIN))) -        bd_handle_special_xattrs(frame, this, loc, NULL, name, xdata); -    else -        STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); - -    return 0; -} - -int -bd_unlink_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, -                     int op_ret, int op_errno, inode_t *inode, struct iatt *buf, -                     dict_t *xattr, struct iatt *postparent) -{ -    bd_gfid_t gfid = { -        0, -    }; -    bd_local_t *local = frame->local; - -    if (buf->ia_nlink > 1) -        goto posix; - -    BD_VALIDATE_LOCAL_OR_GOTO(local, op_errno, out); - -    uuid_utoa_r(inode->gfid, gfid); -    if (bd_delete_lv(this->private, gfid, &op_errno) < 0) { -        if (op_errno != ENOENT) -            goto out; -    } - -posix: -    /* remove posix */ -    STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->unlink, &local->loc, 0, NULL); - -    return 0; -out: -    BD_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int -bd_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, -          dict_t *xdata) -{ -    int op_errno = 0; -    bd_attr_t *bdatt = NULL; -    bd_local_t *local = NULL; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(loc, out); - -    if (bd_inode_ctx_get(loc->inode, this, &bdatt)) { -        STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); -        return 0; -    } - -    local = bd_local_init(frame, this); -    BD_VALIDATE_MEM_ALLOC(local, op_errno, out); - -    loc_copy(&local->loc, loc); - -    STACK_WIND(frame, bd_unlink_lookup_cbk, FIRST_CHILD(this), -               FIRST_CHILD(this)->fops->lookup, loc, NULL); -    return 0; -out: -    BD_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); -    return 0; -} - -int32_t -bd_priv(xlator_t *this) -{ -    return 0; -} - -int32_t -bd_inode(xlator_t *this) -{ -    return 0; -} - -int32_t -bd_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -             int32_t len, dict_t *xdata) -{ -    int op_ret = -1; -    int op_errno = 0; -    int ret = 0; -    int _fd = -1; -    char *alloc_buf = NULL; -    char *buf = NULL; -    int32_t weak_checksum = 0; -    bd_fd_t *bd_fd = NULL; -    unsigned char strong_checksum[SHA256_DIGEST_LENGTH] = {0}; - -    VALIDATE_OR_GOTO(frame, out); -    VALIDATE_OR_GOTO(this, out); -    VALIDATE_OR_GOTO(fd, out); - -    ret = bd_fd_ctx_get(this, fd, &bd_fd); -    if (ret < 0 || !bd_fd) { -        STACK_WIND(frame, default_rchecksum_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata); -        return 0; -    } - -    alloc_buf = page_aligned_alloc(len, &buf); -    if (!alloc_buf) { -        op_errno = ENOMEM; -        goto out; -    } - -    _fd = bd_fd->fd; - -    LOCK(&fd->lock); -    { -        ret = sys_pread(_fd, buf, len, offset); -        if (ret < 0) { -            gf_log(this->name, GF_LOG_WARNING, -                   "pread of %d bytes returned %d (%s)", len, ret, -                   strerror(errno)); -            op_errno = errno; -        } -    } -    UNLOCK(&fd->lock); - -    if (ret < 0) -        goto out; - -    weak_checksum = gf_rsync_weak_checksum((unsigned char *)buf, (size_t)len); -    gf_rsync_strong_checksum((unsigned char *)buf, (size_t)len, -                             (unsigned char *)strong_checksum); - -    op_ret = 0; -out: -    BD_STACK_UNWIND(rchecksum, frame, op_ret, op_errno, weak_checksum, -                    strong_checksum, NULL); - -    GF_FREE(alloc_buf); - -    return 0; -} - -static int -bd_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -            off_t len, dict_t *xdata) -{ -    int32_t ret = 0; -    struct iatt statpre = { -        0, -    }; -    struct iatt statpost = { -        0, -    }; -    bd_attr_t *bdatt = NULL; - -    /* iatt already cached */ -    if (bd_inode_ctx_get(fd->inode, this, &bdatt) < 0) { -        STACK_WIND(frame, default_zerofill_cbk, FIRST_CHILD(this), -                   FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); -        return 0; -    } - -    ret = bd_do_zerofill(frame, this, fd, offset, len, &statpre, &statpost); -    if (ret) -        goto err; - -    STACK_UNWIND_STRICT(zerofill, frame, 0, 0, &statpre, &statpost, NULL); -    return 0; - -err: -    STACK_UNWIND_STRICT(zerofill, frame, -1, (ret == -1 ? 0 : ret), NULL, NULL, -                        NULL); -    return 0; -} - -/** - * notify - when parent sends PARENT_UP, send CHILD_UP event from here - */ -int32_t -notify(xlator_t *this, int32_t event, void *data, ...) -{ -    switch (event) { -        case GF_EVENT_PARENT_UP: { -            /* Tell the parent that bd xlator is up */ -            default_notify(this, GF_EVENT_CHILD_UP, data); -        } break; -        default: -            break; -    } -    return 0; -} - -int32_t -mem_acct_init(xlator_t *this) -{ -    int ret = -1; - -    if (!this) -        return ret; - -    ret = xlator_mem_acct_init(this, gf_bd_mt_end + 1); - -    if (ret != 0) -        gf_log(this->name, GF_LOG_ERROR, -               "Memory accounting init" -               "failed"); - -    return ret; -} - -int -reconfigure(xlator_t *this, dict_t *options) -{ -    int ret = -1; -    bd_priv_t *priv = this->private; - -    GF_OPTION_RECONF("bd-aio", priv->aio_configured, options, bool, out); - -    if (priv->aio_configured) -        bd_aio_on(this); -    else -        bd_aio_off(this); - -    ret = 0; -out: -    return ret; -} - -/** - * bd xlator init - Validate configured VG - */ -int -init(xlator_t *this) -{ -    char *vg_data = NULL; -    char *device = NULL; -    bd_priv_t *_private = NULL; - -    if (!this->children) { -        gf_log(this->name, GF_LOG_CRITICAL, -               "FATAL: storage/bd needs posix as subvolume"); -        return -1; -    } - -    if (!this->parents) { -        gf_log(this->name, GF_LOG_WARNING, -               "Volume is dangling. Please check the volume file."); -    } - -    GF_OPTION_INIT("export", vg_data, str, error); -    GF_OPTION_INIT("device", device, str, error); - -    /* Now we support only LV device */ -    if (strcasecmp(device, BACKEND_VG)) { -        gf_log(this->name, GF_LOG_CRITICAL, "FATAL: unknown %s backend %s", -               BD_XLATOR, device); -        return -1; -    } - -    this->local_pool = mem_pool_new(bd_local_t, 64); -    if (!this->local_pool) { -        gf_log(this->name, GF_LOG_CRITICAL, -               "FATAL: Failed to create bd memory pool"); -        return -1; -    } - -    _private = GF_CALLOC(1, sizeof(*_private), gf_bd_private); -    if (!_private) -        goto error; - -    this->private = _private; -    _private->vg = gf_strdup(vg_data); -    if (!_private->vg) -        goto error; - -    _private->handle = lvm_init(NULL); -    if (!_private->handle) { -        gf_log(this->name, GF_LOG_CRITICAL, "lvm_init failed"); -        goto error; -    } -    _private->caps = BD_CAPS_BD; -    if (bd_scan_vg(this, _private)) -        goto error; - -    _private->aio_init_done = _gf_false; -    _private->aio_capable = _gf_false; - -    GF_OPTION_INIT("bd-aio", _private->aio_configured, bool, error); -    if (_private->aio_configured) { -        if (bd_aio_on(this)) { -            gf_log(this->name, GF_LOG_ERROR, "BD AIO init failed"); -            goto error; -        } -    } - -    _private->caps |= BD_CAPS_OFFLOAD_COPY | BD_CAPS_OFFLOAD_SNAPSHOT | -                      BD_CAPS_OFFLOAD_ZERO; - -    return 0; -error: -    if (_private) { -        GF_FREE(_private->vg); -        if (_private->handle) -            lvm_quit(_private->handle); -        GF_FREE(_private); -    } - -    mem_pool_destroy(this->local_pool); - -    return -1; -} - -void -fini(xlator_t *this) -{ -    bd_priv_t *priv = this->private; -    mem_pool_destroy(this->local_pool); -    this->local_pool = NULL; -    if (!priv) -        return; -    lvm_quit(priv->handle); -    GF_FREE(priv->vg); -    this->private = NULL; -    GF_FREE(priv); -    return; -} - -struct xlator_dumpops dumpops = { -    .priv = bd_priv, -    .inode = bd_inode, -}; - -struct xlator_fops fops = { -    .readdirp = bd_readdirp, -    .lookup = bd_lookup, -    .stat = bd_stat, -    .statfs = bd_statfs, -    .open = bd_open, -    .fstat = bd_fstat, -    .rchecksum = bd_rchecksum, -    .readv = bd_readv, -    .fsync = bd_fsync, -    .setxattr = bd_setxattr, -    .fsetxattr = bd_fsetxattr, -    .removexattr = bd_removexattr, -    .fremovexattr = bd_fremovexattr, -    .truncate = bd_truncate, -    .ftruncate = bd_ftruncate, -    .writev = bd_writev, -    .getxattr = bd_getxattr, -    .fgetxattr = bd_fgetxattr, -    .unlink = bd_unlink, -    .link = bd_link, -    .flush = bd_flush, -    .setattr = bd_setattr, -    .discard = bd_discard, -    .zerofill = bd_zerofill, -}; - -struct xlator_cbks cbks = { -    .release = bd_release, -    .forget = bd_forget, -}; - -struct volume_options options[] = { -    {.key = {"export"}, .type = GF_OPTION_TYPE_STR}, -    {.key = {"device"}, -     .type = GF_OPTION_TYPE_STR, -     .default_value = BACKEND_VG}, -    {.key = {"bd-aio"}, -     .type = GF_OPTION_TYPE_BOOL, -     .default_value = "off", -     .description = "Support for native Linux AIO"}, - -    {.key = {NULL}}}; diff --git a/xlators/storage/bd/src/bd.h b/xlators/storage/bd/src/bd.h deleted file mode 100644 index f73781a0fe6..00000000000 --- a/xlators/storage/bd/src/bd.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -  BD translator - Exports Block devices on server side as regular -  files to client - -  Copyright IBM, Corp. 2012 - -  This file is part of GlusterFS. - -  Author: -  M. Mohan Kumar <mohan@in.ibm.com> - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _BD_H -#define _BD_H - -#ifdef HAVE_LIBAIO -#include <libaio.h> -#endif - -#include <glusterfs/xlator.h> -#include <glusterfs/mem-types.h> - -#define BD_XLATOR "block device mapper xlator" -#define BACKEND_VG "vg" -#define GF_XATTR "user.glusterfs" -#define BD_XATTR GF_XATTR ".bd" - -#define BD_LV "lv" -#define BD_THIN "thin" - -#define VOL_TYPE "volume.type" -#define VOL_CAPS "volume.caps" - -#define ALIGN_SIZE 4096 - -#define BD_CAPS_BD 0x01 -#define BD_CAPS_THIN 0x02 -#define BD_CAPS_OFFLOAD_COPY 0x04 -#define BD_CAPS_OFFLOAD_SNAPSHOT 0x08 -#define BD_CAPS_OFFLOAD_ZERO 0x20 - -#define BD_CLONE "clone" -#define BD_SNAPSHOT "snapshot" -#define BD_MERGE "merge" -#define BD_ORIGIN "list-origin" - -#define IOV_NR 4 -#define IOV_SIZE (64 * 1024) - -#define ALIGN_SIZE 4096 -#define LINKTO "trusted.glusterfs.dht.linkto" - -#define MAX_NO_VECT 1024 - -#define BD_VALIDATE_MEM_ALLOC(buff, op_errno, label)                           \ -    if (!buff) {                                                               \ -        op_errno = ENOMEM;                                                     \ -        gf_log(this->name, GF_LOG_ERROR, "out of memory");                     \ -        goto label;                                                            \ -    } - -#define BD_VALIDATE_LOCAL_OR_GOTO(local, op_errno, label)                      \ -    if (!local) {                                                              \ -        op_errno = EINVAL;                                                     \ -        goto label;                                                            \ -    } - -#define BD_STACK_UNWIND(typ, frame, args...)                                   \ -    do {                                                                       \ -        bd_local_t *__local = frame->local;                                    \ -        xlator_t *__this = frame->this;                                        \ -                                                                               \ -        frame->local = NULL;                                                   \ -        STACK_UNWIND_STRICT(typ, frame, args);                                 \ -        if (__local)                                                           \ -            bd_local_free(__this, __local);                                    \ -    } while (0) - -typedef char bd_gfid_t[GF_UUID_BUF_SIZE]; - -/** - * bd_fd - internal structure - */ -typedef struct bd_fd { -    int fd; -    int32_t flag; -    int odirect; -} bd_fd_t; - -typedef struct bd_priv { -    lvm_t handle; -    char *vg; -    char *pool; -    int caps; -    gf_boolean_t aio_init_done; -    gf_boolean_t aio_capable; -    gf_boolean_t aio_configured; -#ifdef HAVE_LIBAIO -    io_context_t ctxp; -    pthread_t aiothread; -#endif -} bd_priv_t; - -typedef enum bd_type { -    BD_TYPE_NONE, -    BD_TYPE_LV, -} bd_type_t; - -typedef struct { -    struct iatt iatt; -    char *type; -} bd_attr_t; - -typedef enum { -    BD_OF_NONE, -    BD_OF_CLONE, -    BD_OF_SNAPSHOT, -    BD_OF_MERGE, -} bd_offload_t; - -typedef struct { -    dict_t *dict; -    bd_attr_t *bdatt; -    inode_t *inode; -    loc_t loc; -    fd_t *fd; -    data_t *data; /* for setxattr */ -    bd_offload_t offload; -    uint64_t size; -    loc_t *dloc; -} bd_local_t; - -/* Prototypes */ -int -bd_inode_ctx_set(inode_t *inode, xlator_t *this, bd_attr_t *ctx); -int -bd_inode_ctx_get(inode_t *inode, xlator_t *this, bd_attr_t **ctx); -int -bd_scan_vg(xlator_t *this, bd_priv_t *priv); -bd_local_t * -bd_local_init(call_frame_t *frame, xlator_t *this); -void -bd_local_free(xlator_t *this, bd_local_t *local); -int -bd_fd_ctx_get(xlator_t *this, fd_t *fd, bd_fd_t **bdfd); -char * -page_aligned_alloc(size_t size, char **aligned_buf); -int -bd_validate_bd_xattr(xlator_t *this, char *bd, char **type, uint64_t *lv_size, -                     uuid_t uuid); -uint64_t -bd_get_default_extent(bd_priv_t *priv); -uint64_t -bd_adjust_size(bd_priv_t *priv, size_t size); -int -bd_create(uuid_t uuid, uint64_t size, char *type, bd_priv_t *priv); -int -bd_resize(bd_priv_t *priv, uuid_t uuid, size_t size); -int -bd_delete_lv(bd_priv_t *priv, const char *lv_name, int *op_errno); -int -bd_snapshot_create(bd_local_t *local, bd_priv_t *priv); -int -bd_clone(bd_local_t *local, bd_priv_t *priv); - -int -bd_merge(bd_priv_t *priv, uuid_t gfid); -int -bd_get_origin(bd_priv_t *priv, loc_t *loc, fd_t *fd, dict_t *dict); -void -bd_update_amtime(struct iatt *iatt, int flag); -int -bd_snapshot_create(bd_local_t *local, bd_priv_t *priv); -int -bd_clone(bd_local_t *local, bd_priv_t *priv); -int -bd_merge(bd_priv_t *priv, uuid_t gfid); -int -bd_get_origin(bd_priv_t *priv, loc_t *loc, fd_t *fd, dict_t *dict); -int -bd_do_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, -               size_t len, struct iatt *prebuf, struct iatt *postbuf); - -#endif  | 
