/*
  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.
*/

/* File: cloudsync-autogen-fops-tmpl.c
 * This file contains the CLOUDSYNC autogenerated FOPs. This is run through
 * the code generator, generator.py to generate the required FOPs.
 */

#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif

#include <dlfcn.h>

#include <glusterfs/glusterfs.h>
#include <glusterfs/xlator.h>
#include <glusterfs/defaults.h>
#include "cloudsync.h"
#include "cloudsync-common.h"
#include <glusterfs/call-stub.h>

/* BEGIN GENERATED CODE - DO NOT MODIFY */

int32_t
cs_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)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second fsync, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful fsync => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", fsync successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);

        return 0;
}


int32_t
cs_resume_fsync (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	int32_t flags,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_fsync_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync,
                    fd, flags, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_fsync (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	int32_t flags,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_FSYNC);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_fsync_stub (frame, cs_resume_fsync,
                                       fd, flags, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_fsync_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync,
                            fd, flags, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               dict_t * xdata)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second flush, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful flush => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", flush successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (flush, frame, op_ret, op_errno, xdata);

        return 0;
}


int32_t
cs_resume_flush (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_flush_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush,
                    fd, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_flush (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_FLUSH);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_flush_stub (frame, cs_resume_flush,
                                       fd, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_flush_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush,
                            fd, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (flush, frame, -1, op_errno, NULL);

        return 0;
}


int32_t
cs_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)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second writev, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful writev => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", writev successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);

        return 0;
}


int32_t
cs_resume_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    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_writev_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
                    fd, vector, count, off, flags, iobref, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_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                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_WRITE);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_writev_stub (frame, cs_resume_writev,
                                       fd, vector, count, off, flags, iobref, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_writev_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
                            fd, vector, count, off, flags, iobref, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               dict_t * xdata)
{
        int              ret = 0;
        uint64_t         val = 0;
        loc_t           *loc = NULL;
        cs_local_t      *local = NULL;

        local = frame->local;

        loc = &local->loc;

        if (op_ret == 0) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (!ret) {
                        ret = __cs_inode_ctx_update (this, loc->inode, val);
                        if (ret) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "ctx update failed");
                        }
                }
        } else {
                cs_inode_ctx_reset (this, loc->inode);
        }

        CS_STACK_UNWIND (access, frame, op_ret, op_errno, xdata);

        return 0;
}


int32_t
cs_access (call_frame_t *frame, xlator_t *this,
           loc_t * loc,
	int32_t mask,
	dict_t * xdata)
{
        int              op_errno = EINVAL;
        cs_local_t      *local = NULL;
        int              ret   = 0;

        local = cs_local_init (this, frame, loc, NULL, GF_FOP_ACCESS);
        if (!local) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local is NULL");
                op_errno = ENOMEM;
                goto err;
        }

        if (loc->inode->ia_type == IA_IFDIR)
                goto wind;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

wind:
        STACK_WIND (frame, cs_access_cbk, FIRST_CHILD(this),
                    FIRST_CHILD(this)->fops->access,
                    loc, mask, xdata);

        return 0;
err:
        CS_STACK_UNWIND (access, frame, -1, op_errno, NULL);

        return 0;
}


int32_t
cs_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)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second ftruncate, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful ftruncate => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", ftruncate successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata);

        return 0;
}


int32_t
cs_resume_ftruncate (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	off_t offset,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_ftruncate_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate,
                    fd, offset, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_ftruncate (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	off_t offset,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_FTRUNCATE);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_ftruncate_stub (frame, cs_resume_ftruncate,
                                       fd, offset, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_ftruncate_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate,
                            fd, offset, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               uint32_t weak_cksum,
	uint8_t * strong_cksum,
	dict_t * xdata)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second rchecksum, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful rchecksum => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", rchecksum successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (rchecksum, frame, op_ret, op_errno, weak_cksum, strong_cksum, xdata);

        return 0;
}


int32_t
cs_resume_rchecksum (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	off_t offset,
	int32_t len,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_rchecksum_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->rchecksum,
                    fd, offset, len, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_rchecksum (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	off_t offset,
	int32_t len,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_RCHECKSUM);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_rchecksum_stub (frame, cs_resume_rchecksum,
                                       fd, offset, len, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_rchecksum_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->rchecksum,
                            fd, offset, len, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (rchecksum, frame, -1, op_errno, -1, NULL, NULL);

        return 0;
}


int32_t
cs_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               struct iatt * statpre,
	struct iatt * statpost,
	dict_t * xdata)
{
        int              ret = 0;
        uint64_t         val = 0;
        loc_t           *loc = NULL;
        cs_local_t      *local = NULL;

        local = frame->local;

        loc = &local->loc;

        if (op_ret == 0) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (!ret) {
                        ret = __cs_inode_ctx_update (this, loc->inode, val);
                        if (ret) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "ctx update failed");
                        }
                }
        } else {
                cs_inode_ctx_reset (this, loc->inode);
        }

        CS_STACK_UNWIND (setattr, frame, op_ret, op_errno, statpre, statpost, xdata);

        return 0;
}


int32_t
cs_setattr (call_frame_t *frame, xlator_t *this,
           loc_t * loc,
	struct iatt * stbuf,
	int32_t valid,
	dict_t * xdata)
{
        int              op_errno = EINVAL;
        cs_local_t      *local = NULL;
        int              ret   = 0;

        local = cs_local_init (this, frame, loc, NULL, GF_FOP_SETATTR);
        if (!local) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local is NULL");
                op_errno = ENOMEM;
                goto err;
        }

        if (loc->inode->ia_type == IA_IFDIR)
                goto wind;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

wind:
        STACK_WIND (frame, cs_setattr_cbk, FIRST_CHILD(this),
                    FIRST_CHILD(this)->fops->setattr,
                    loc, stbuf, valid, xdata);

        return 0;
err:
        CS_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_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)
{
        int              ret = 0;
        uint64_t         val = 0;
        loc_t           *loc = NULL;
        cs_local_t      *local = NULL;

        local = frame->local;

        loc = &local->loc;

        if (op_ret == 0) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (!ret) {
                        ret = __cs_inode_ctx_update (this, loc->inode, val);
                        if (ret) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "ctx update failed");
                        }
                }
        } else {
                cs_inode_ctx_reset (this, loc->inode);
        }

        CS_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);

        return 0;
}


int32_t
cs_stat (call_frame_t *frame, xlator_t *this,
           loc_t * loc,
	dict_t * xdata)
{
        int              op_errno = EINVAL;
        cs_local_t      *local = NULL;
        int              ret   = 0;

        local = cs_local_init (this, frame, loc, NULL, GF_FOP_STAT);
        if (!local) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local is NULL");
                op_errno = ENOMEM;
                goto err;
        }

        if (loc->inode->ia_type == IA_IFDIR)
                goto wind;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

wind:
        STACK_WIND (frame, cs_stat_cbk, FIRST_CHILD(this),
                    FIRST_CHILD(this)->fops->stat,
                    loc, xdata);

        return 0;
err:
        CS_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);

        return 0;
}


int32_t
cs_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)
{
        int              ret = 0;
        uint64_t         val = 0;
        loc_t           *loc = NULL;
        cs_local_t      *local = NULL;

        local = frame->local;

        loc = &local->loc;

        if (op_ret == 0) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (!ret) {
                        ret = __cs_inode_ctx_update (this, loc->inode, val);
                        if (ret) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "ctx update failed");
                        }
                }
        } else {
                cs_inode_ctx_reset (this, loc->inode);
        }

        CS_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent);

        return 0;
}


int32_t
cs_lookup (call_frame_t *frame, xlator_t *this,
           loc_t * loc,
	dict_t * xdata)
{
        int              op_errno = EINVAL;
        cs_local_t      *local = NULL;
        int              ret   = 0;

        local = cs_local_init (this, frame, loc, NULL, GF_FOP_LOOKUP);
        if (!local) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local is NULL");
                op_errno = ENOMEM;
                goto err;
        }

        if (loc->inode->ia_type == IA_IFDIR)
                goto wind;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

wind:
        STACK_WIND (frame, cs_lookup_cbk, FIRST_CHILD(this),
                    FIRST_CHILD(this)->fops->lookup,
                    loc, xdata);

        return 0;
err:
        CS_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_fallocate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               struct iatt * pre,
	struct iatt * post,
	dict_t * xdata)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second fallocate, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful fallocate => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", fallocate successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (fallocate, frame, op_ret, op_errno, pre, post, xdata);

        return 0;
}


int32_t
cs_resume_fallocate (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	int32_t keep_size,
	off_t offset,
	size_t len,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_fallocate_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate,
                    fd, keep_size, offset, len, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_fallocate (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	int32_t keep_size,
	off_t offset,
	size_t len,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_FALLOCATE);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_fallocate_stub (frame, cs_resume_fallocate,
                                       fd, keep_size, offset, len, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_fallocate_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate,
                            fd, keep_size, offset, len, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_discard_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               struct iatt * pre,
	struct iatt * post,
	dict_t * xdata)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second discard, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful discard => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", discard successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (discard, frame, op_ret, op_errno, pre, post, xdata);

        return 0;
}


int32_t
cs_resume_discard (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	off_t offset,
	size_t len,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_discard_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard,
                    fd, offset, len, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_discard (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	off_t offset,
	size_t len,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_DISCARD);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_discard_stub (frame, cs_resume_discard,
                                       fd, offset, len, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_discard_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard,
                            fd, offset, len, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (discard, frame, -1, op_errno, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_zerofill_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               struct iatt * pre,
	struct iatt * post,
	dict_t * xdata)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second zerofill, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful zerofill => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", zerofill successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (zerofill, frame, op_ret, op_errno, pre, post, xdata);

        return 0;
}


int32_t
cs_resume_zerofill (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	off_t offset,
	off_t len,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_zerofill_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill,
                    fd, offset, len, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_zerofill (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	off_t offset,
	off_t len,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_ZEROFILL);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_zerofill_stub (frame, cs_resume_zerofill,
                                       fd, offset, len, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_zerofill_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill,
                            fd, offset, len, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (zerofill, frame, -1, op_errno, NULL, NULL, NULL);

        return 0;
}


int32_t
cs_seek_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
               int32_t op_ret, int32_t op_errno,
               off_t offset,
	dict_t * xdata)
{
        cs_local_t      *local = NULL;
        int              ret = 0;
        uint64_t         val = 0;
        fd_t            *fd = NULL;

        local = frame->local;
        fd = local->fd;

        /* Do we need lock here? */
        local->call_cnt++;

        if (op_ret == -1) {
                ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val);
                if (ret == 0) {
                        if (val == GF_CS_ERROR) {
                                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                        "could not get file state, unwinding");
                                op_ret = -1;
                                op_errno = EIO;
                                goto unwind;
                        } else {
                                __cs_inode_ctx_update (this, fd->inode, val);
                                gf_msg (this->name, GF_LOG_INFO, 0, 0,
                                        " state = %" PRIu64, val);

                                if (local->call_cnt == 1 &&
                                    (val == GF_CS_REMOTE ||
                                     val == GF_CS_DOWNLOADING))  {
                                        gf_msg (this->name, GF_LOG_INFO, 0,
                                                0, " will repair and download "
                                                "the file, current state : %"
                                                PRIu64, val);
                                        goto repair;
                                } else {
                                        gf_msg (this->name, GF_LOG_ERROR, 0, 0,
                                                "second seek, Unwinding");
                                        goto unwind;
                                }
                        }
                } else {
                        gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state "
                                "could not be figured, unwinding");
                        goto unwind;
                }
        } else {
                /* successful seek => file is local */
                __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL);
                gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL"
                        ", seek successful");

                goto unwind;
        }

repair:
        ret = locate_and_execute (frame);
        if (ret) {
                goto unwind;
        }

        return 0;

unwind:
        CS_STACK_UNWIND (seek, frame, op_ret, op_errno, offset, xdata);

        return 0;
}


int32_t
cs_resume_seek (call_frame_t *frame, xlator_t *this,
                  fd_t * fd,
	off_t offset,
	gf_seek_what_t what,
	dict_t * xdata)
{
        int              ret    = 0;

        ret = cs_resume_postprocess (this, frame, fd->inode);
        if (ret) {
                goto unwind;
        }

        cs_inodelk_unlock (frame);

        STACK_WIND (frame, cs_seek_cbk,
                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->seek,
                    fd, offset, what, xdata);

        return 0;

unwind:

        cs_inodelk_unlock (frame);

        cs_common_cbk (frame);

        return 0;
}


int32_t
cs_seek (call_frame_t *frame, xlator_t *this,
           fd_t * fd,
	off_t offset,
	gf_seek_what_t what,
	dict_t * xdata)
{
        int                         op_errno        = EINVAL ;
        cs_local_t                 *local           = NULL;
        int                         ret             = 0;
        cs_inode_ctx_t             *ctx             = NULL;
        gf_cs_obj_state             state           = -1;

        VALIDATE_OR_GOTO (frame, err);
        VALIDATE_OR_GOTO (this, err);
        VALIDATE_OR_GOTO (fd, err);

        local = cs_local_init (this, frame, NULL, fd, GF_FOP_SEEK);
        if (!local) {

                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed");
                op_errno = ENOMEM;
                goto err;
        }

        __cs_inode_ctx_get (this, fd->inode, &ctx);

        if (ctx)
                state = __cs_get_file_state (fd->inode, ctx);
        else
                state = GF_CS_LOCAL;

        xdata = xdata ? dict_ref (xdata) : dict_new ();

        if (!xdata) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }

        local->xattr_req = xdata;

        ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1);
        if (ret) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:"
                        " %s", GF_CS_OBJECT_STATUS);
                goto err;
        }

        local->stub = fop_seek_stub (frame, cs_resume_seek,
                                       fd, offset, what, xdata);
        if (!local->stub) {
                gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
                op_errno = ENOMEM;
                goto err;
        }


        if (state == GF_CS_LOCAL) {
                STACK_WIND (frame, cs_seek_cbk,
                            FIRST_CHILD(this), FIRST_CHILD(this)->fops->seek,
                            fd, offset, what, xdata);
        } else {
                local->call_cnt++;
                ret = locate_and_execute (frame);
                if (ret) {
                        op_errno = ENOMEM;
                        goto err;
                }
        }

        return 0;

err:
        CS_STACK_UNWIND (seek, frame, -1, op_errno, -1, NULL);

        return 0;
}

/* END GENERATED CODE */
