Blame xlators/features/utime/src/utime.c

Packit Service e080da
/*
Packit Service e080da
  Copyright (c) 2018 Red Hat, Inc. <http://www.redhat.com>
Packit Service e080da
  This file is part of GlusterFS.
Packit Service e080da
Packit Service e080da
  This file is licensed to you under your choice of the GNU Lesser
Packit Service e080da
  General Public License, version 3 or any later version (LGPLv3 or
Packit Service e080da
  later), or the GNU General Public License, version 2 (GPLv2), in all
Packit Service e080da
  cases as published by the Free Software Foundation.
Packit Service e080da
*/
Packit Service e080da
Packit Service e080da
#include "utime.h"
Packit Service a90fdc
#include "utime-helpers.h"
Packit Service e080da
#include "utime-messages.h"
Packit Service e080da
#include "utime-mem-types.h"
Packit Service a90fdc
#include <glusterfs/call-stub.h>
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_invalidate(xlator_t *this, inode_t *inode)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_forget(xlator_t *this, inode_t *inode)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_client_destroy(xlator_t *this, client_t *client)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
void
Packit Service e080da
gf_utime_ictxmerge(xlator_t *this, fd_t *fd, inode_t *inode,
Packit Service e080da
                   inode_t *linked_inode)
Packit Service e080da
{
Packit Service e080da
    return;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_release(xlator_t *this, fd_t *fd)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_releasedir(xlator_t *this, fd_t *fd)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_client_disconnect(xlator_t *this, client_t *client)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_fdctx_to_dict(xlator_t *this, fd_t *fd, dict_t *dict)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_inode(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_inode_to_dict(xlator_t *this, dict_t *dict)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_history(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_fd(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_fd_to_dict(xlator_t *this, dict_t *dict)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_fdctx(xlator_t *this, fd_t *fd)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_inodectx(xlator_t *this, inode_t *ino)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_inodectx_to_dict(xlator_t *this, inode_t *ino, dict_t *dict)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
gf_utime_priv(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
mem_acct_init(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    if (xlator_mem_acct_init(this, utime_mt_end + 1) != 0) {
Packit Service e080da
        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY,
Packit Service e080da
               "Memory accounting initialization failed.");
Packit Service e080da
        return -1;
Packit Service e080da
    }
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service a90fdc
gf_utime_set_mdata_setxattr_cbk(call_frame_t *frame, void *cookie,
Packit Service a90fdc
                                xlator_t *this, int op_ret, int op_errno,
Packit Service a90fdc
                                dict_t *xdata)
Packit Service a90fdc
{
Packit Service a90fdc
    call_stub_t *stub = frame->local;
Packit Service a90fdc
    /* Don't fail lookup if mdata setxattr fails */
Packit Service a90fdc
    if (op_ret) {
Packit Service a90fdc
        gf_msg(this->name, GF_LOG_ERROR, op_errno, UTIME_MSG_SET_MDATA_FAILED,
Packit Service a90fdc
               "dict set of key for set-ctime-mdata failed");
Packit Service a90fdc
    }
Packit Service a90fdc
    frame->local = NULL;
Packit Service a90fdc
    call_resume(stub);
Packit Service a90fdc
    return 0;
Packit Service a90fdc
}
Packit Service a90fdc
Packit Service a90fdc
int32_t
Packit Service a90fdc
gf_utime_set_mdata_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
Packit Service a90fdc
                              int32_t op_ret, int32_t op_errno, inode_t *inode,
Packit Service a90fdc
                              struct iatt *stbuf, dict_t *xdata,
Packit Service a90fdc
                              struct iatt *postparent)
Packit Service a90fdc
{
Packit Service a90fdc
    dict_t *dict = NULL;
Packit Service a90fdc
    struct mdata_iatt *mdata = NULL;
Packit Service a90fdc
    int ret = 0;
Packit Service a90fdc
    loc_t loc = {
Packit Service a90fdc
        0,
Packit Service a90fdc
    };
Packit Service a90fdc
Packit Service a90fdc
    if (!op_ret && dict_get(xdata, GF_XATTR_MDATA_KEY) == NULL) {
Packit Service a90fdc
        dict = dict_new();
Packit Service a90fdc
        if (!dict) {
Packit Service a90fdc
            op_errno = ENOMEM;
Packit Service a90fdc
            goto err;
Packit Service a90fdc
        }
Packit Service a90fdc
        mdata = GF_MALLOC(sizeof(struct mdata_iatt), gf_common_mt_char);
Packit Service a90fdc
        if (mdata == NULL) {
Packit Service a90fdc
            op_errno = ENOMEM;
Packit Service a90fdc
            goto err;
Packit Service a90fdc
        }
Packit Service a90fdc
        iatt_to_mdata(mdata, stbuf);
Packit Service a90fdc
        ret = dict_set_mdata(dict, CTIME_MDATA_XDATA_KEY, mdata, _gf_false);
Packit Service a90fdc
        if (ret < 0) {
Packit Service a90fdc
            gf_msg(this->name, GF_LOG_WARNING, ENOMEM, UTIME_MSG_NO_MEMORY,
Packit Service a90fdc
                   "dict set of key for set-ctime-mdata failed");
Packit Service a90fdc
            goto err;
Packit Service a90fdc
        }
Packit Service a90fdc
        frame->local = fop_lookup_cbk_stub(frame, default_lookup_cbk, op_ret,
Packit Service a90fdc
                                           op_errno, inode, stbuf, xdata,
Packit Service a90fdc
                                           postparent);
Packit Service a90fdc
        if (!frame->local) {
Packit Service a90fdc
            gf_msg(this->name, GF_LOG_WARNING, ENOMEM, UTIME_MSG_NO_MEMORY,
Packit Service a90fdc
                   "lookup_cbk stub allocation failed");
Packit Service a90fdc
            goto stub_err;
Packit Service a90fdc
        }
Packit Service a90fdc
Packit Service a90fdc
        loc.inode = inode_ref(inode);
Packit Service a90fdc
        gf_uuid_copy(loc.gfid, stbuf->ia_gfid);
Packit Service a90fdc
        STACK_WIND(frame, gf_utime_set_mdata_setxattr_cbk, FIRST_CHILD(this),
Packit Service a90fdc
                   FIRST_CHILD(this)->fops->setxattr, &loc, dict, 0, NULL);
Packit Service a90fdc
Packit Service a90fdc
        dict_unref(dict);
Packit Service a90fdc
        inode_unref(loc.inode);
Packit Service a90fdc
        return 0;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, stbuf, xdata,
Packit Service a90fdc
                        postparent);
Packit Service a90fdc
    return 0;
Packit Service a90fdc
Packit Service a90fdc
err:
Packit Service a90fdc
    if (mdata) {
Packit Service a90fdc
        GF_FREE(mdata);
Packit Service a90fdc
    }
Packit Service a90fdc
stub_err:
Packit Service a90fdc
    if (dict) {
Packit Service a90fdc
        dict_unref(dict);
Packit Service a90fdc
    }
Packit Service a90fdc
    STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
Packit Service a90fdc
    return 0;
Packit Service a90fdc
}
Packit Service a90fdc
Packit Service a90fdc
int
Packit Service a90fdc
gf_utime_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
Packit Service a90fdc
{
Packit Service a90fdc
    int op_errno = -1;
Packit Service a90fdc
    int ret = -1;
Packit Service a90fdc
Packit Service a90fdc
    VALIDATE_OR_GOTO(frame, err);
Packit Service a90fdc
    VALIDATE_OR_GOTO(this, err);
Packit Service a90fdc
    VALIDATE_OR_GOTO(loc, err);
Packit Service a90fdc
    VALIDATE_OR_GOTO(loc->inode, err);
Packit Service a90fdc
Packit Service a90fdc
    xdata = xdata ? dict_ref(xdata) : dict_new();
Packit Service a90fdc
    if (!xdata) {
Packit Service a90fdc
        op_errno = ENOMEM;
Packit Service a90fdc
        goto err;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    ret = dict_set_int8(xdata, GF_XATTR_MDATA_KEY, 1);
Packit Service a90fdc
    if (ret < 0) {
Packit Service a90fdc
        gf_msg(this->name, GF_LOG_WARNING, -ret, UTIME_MSG_DICT_SET_FAILED,
Packit Service a90fdc
               "%s: Unable to set dict value for %s", loc->path,
Packit Service a90fdc
               GF_XATTR_MDATA_KEY);
Packit Service a90fdc
        op_errno = -ret;
Packit Service a90fdc
        goto free_dict;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    STACK_WIND(frame, gf_utime_set_mdata_lookup_cbk, FIRST_CHILD(this),
Packit Service a90fdc
               FIRST_CHILD(this)->fops->lookup, loc, xdata);
Packit Service a90fdc
    dict_unref(xdata);
Packit Service a90fdc
    return 0;
Packit Service a90fdc
Packit Service a90fdc
free_dict:
Packit Service a90fdc
    dict_unref(xdata);
Packit Service a90fdc
err:
Packit Service a90fdc
    STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
Packit Service a90fdc
    return 0;
Packit Service a90fdc
}
Packit Service a90fdc
Packit Service a90fdc
int32_t
Packit Service e080da
init(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    utime_priv_t *utime = NULL;
Packit Service e080da
Packit Service e080da
    utime = GF_MALLOC(sizeof(*utime), utime_mt_utime_t);
Packit Service e080da
    if (utime == NULL) {
Packit Service e080da
        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY,
Packit Service e080da
               "Failed to allocate private memory.");
Packit Service e080da
        return -1;
Packit Service e080da
    }
Packit Service e080da
    memset(utime, 0, sizeof(*utime));
Packit Service e080da
Packit Service e080da
    this->private = utime;
Packit Service e080da
    GF_OPTION_INIT("noatime", utime->noatime, bool, err);
Packit Service e080da
Packit Service e080da
    return 0;
Packit Service e080da
err:
Packit Service e080da
    return -1;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
void
Packit Service e080da
fini(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    utime_priv_t *utime = NULL;
Packit Service e080da
Packit Service e080da
    utime = this->private;
Packit Service e080da
    GF_FREE(utime);
Packit Service e080da
    return;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int32_t
Packit Service e080da
reconfigure(xlator_t *this, dict_t *options)
Packit Service e080da
{
Packit Service e080da
    utime_priv_t *utime = this->private;
Packit Service e080da
Packit Service e080da
    GF_OPTION_RECONF("noatime", utime->noatime, options, bool, err);
Packit Service e080da
Packit Service e080da
    return 0;
Packit Service e080da
err:
Packit Service e080da
    return -1;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
notify(xlator_t *this, int event, void *data, ...)
Packit Service e080da
{
Packit Service e080da
    return default_notify(this, event, data);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
struct xlator_fops fops = {
Packit Service a90fdc
    .rename = gf_utime_rename,
Packit Service a90fdc
    .mknod = gf_utime_mknod,
Packit Service a90fdc
    .readv = gf_utime_readv,
Packit Service a90fdc
    .fremovexattr = gf_utime_fremovexattr,
Packit Service a90fdc
    .open = gf_utime_open,
Packit Service a90fdc
    .create = gf_utime_create,
Packit Service a90fdc
    .mkdir = gf_utime_mkdir,
Packit Service a90fdc
    .writev = gf_utime_writev,
Packit Service a90fdc
    .rmdir = gf_utime_rmdir,
Packit Service a90fdc
    .fallocate = gf_utime_fallocate,
Packit Service a90fdc
    .truncate = gf_utime_truncate,
Packit Service a90fdc
    .symlink = gf_utime_symlink,
Packit Service a90fdc
    .zerofill = gf_utime_zerofill,
Packit Service a90fdc
    .link = gf_utime_link,
Packit Service a90fdc
    .ftruncate = gf_utime_ftruncate,
Packit Service a90fdc
    .unlink = gf_utime_unlink,
Packit Service a90fdc
    .setattr = gf_utime_setattr,
Packit Service a90fdc
    .fsetattr = gf_utime_fsetattr,
Packit Service a90fdc
    .opendir = gf_utime_opendir,
Packit Service a90fdc
    .removexattr = gf_utime_removexattr,
Packit Service a90fdc
    .lookup = gf_utime_lookup,
Packit Service e080da
};
Packit Service e080da
struct xlator_cbks cbks = {
Packit Service e080da
    .invalidate = gf_utime_invalidate,
Packit Service e080da
    .forget = gf_utime_forget,
Packit Service e080da
    .client_destroy = gf_utime_client_destroy,
Packit Service e080da
    .ictxmerge = gf_utime_ictxmerge,
Packit Service e080da
    .release = gf_utime_release,
Packit Service e080da
    .releasedir = gf_utime_releasedir,
Packit Service e080da
    .client_disconnect = gf_utime_client_disconnect,
Packit Service e080da
};
Packit Service e080da
struct xlator_dumpops dumpops = {
Packit Service e080da
    .fdctx_to_dict = gf_utime_fdctx_to_dict,
Packit Service e080da
    .inode = gf_utime_inode,
Packit Service e080da
    .inode_to_dict = gf_utime_inode_to_dict,
Packit Service e080da
    .history = gf_utime_history,
Packit Service e080da
    .fd = gf_utime_fd,
Packit Service e080da
    .fd_to_dict = gf_utime_fd_to_dict,
Packit Service e080da
    .fdctx = gf_utime_fdctx,
Packit Service e080da
    .inodectx = gf_utime_inodectx,
Packit Service e080da
    .inodectx_to_dict = gf_utime_inodectx_to_dict,
Packit Service e080da
    .priv_to_dict = gf_utime_priv_to_dict,
Packit Service e080da
    .priv = gf_utime_priv,
Packit Service e080da
};
Packit Service e080da
Packit Service e080da
struct volume_options options[] = {
Packit Service e080da
    {.key = {"noatime"},
Packit Service e080da
     .type = GF_OPTION_TYPE_BOOL,
Packit Service e080da
     .default_value = "on",
Packit Service e080da
     .op_version = {GD_OP_VERSION_5_0},
Packit Service e080da
     .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC,
Packit Service e080da
     .tags = {"ctime"},
Packit Service e080da
     .description = "Enable/Disable atime updation when ctime feature is "
Packit Service e080da
                    "enabled. When noatime is on, atime is not updated with "
Packit Service e080da
                    "ctime feature enabled and vice versa."},
Packit Service e080da
    {.key = {NULL}}};
Packit Service e080da
Packit Service e080da
xlator_api_t xlator_api = {
Packit Service e080da
    .init = init,
Packit Service e080da
    .fini = fini,
Packit Service e080da
    .notify = notify,
Packit Service e080da
    .reconfigure = reconfigure,
Packit Service e080da
    .mem_acct_init = mem_acct_init,
Packit Service e080da
    .op_version = {GD_OP_VERSION_5_0},
Packit Service e080da
    .dumpops = &dumpops,
Packit Service e080da
    .fops = &fops,
Packit Service e080da
    .cbks = &cbks,
Packit Service e080da
    .options = options,
Packit Service e080da
    .identifier = "utime",
Packit Service e080da
    .category = GF_MAINTAINED,
Packit Service e080da
};