diff options
| author | Anuradha Talur <atalur@redhat.com> | 2016-05-02 00:36:30 +0530 | 
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2016-05-01 18:05:31 -0700 | 
| commit | 60e340481ad5496e920722e8267572fa26cf2822 (patch) | |
| tree | 1530ba672669216ee67c6217443a4c1d30afd592 /xlators/protocol/server/src/server-common.c | |
| parent | a15195794c336ed0e272076a128c56b171cae12f (diff) | |
protocol/server: Implementation of compound fopv3.9dev
Change-Id: I981258afa527337dd2ad33eecba7fc8084238e6d
BUG: 1303829
Signed-off-by: Anuradha Talur <atalur@redhat.com>
Reviewed-on: http://review.gluster.org/14137
Smoke: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'xlators/protocol/server/src/server-common.c')
| -rw-r--r-- | xlators/protocol/server/src/server-common.c | 472 | 
1 files changed, 472 insertions, 0 deletions
diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c new file mode 100644 index 00000000000..fd6749a4df7 --- /dev/null +++ b/xlators/protocol/server/src/server-common.c @@ -0,0 +1,472 @@ +#include "server.h" +#include "defaults.h" +#include "rpc-common-xdr.h" +#include "glusterfs3-xdr.h" +#include "glusterfs3.h" +#include "compat-errno.h" +#include "server-messages.h" +#include "defaults.h" +#include "fd.h" +#include "xdr-nfs3.h" + +void +server_post_stat (gfs3_stat_rsp *rsp, struct iatt *stbuf) +{ +        gf_stat_from_iatt (&rsp->stat, stbuf); +} + +void +server_post_readlink (gfs3_readlink_rsp *rsp, struct iatt *stbuf, +                      const char *buf) +{ +        gf_stat_from_iatt (&rsp->buf, stbuf); +        rsp->path = (char *)buf; + +        if (!rsp->path) +                rsp->path = ""; +} + +void +server_post_mknod (server_state_t *state, gfs3_mknod_rsp *rsp, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, inode_t *inode) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); +        inode_lookup (link_inode); +        inode_unref  (link_inode); +} + +void +server_post_mkdir (server_state_t *state, gfs3_mkdir_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); +        inode_lookup (link_inode); +        inode_unref (link_inode); + +} + +void +server_post_unlink (server_state_t *state, gfs3_unlink_rsp *rsp, +                    struct iatt *preparent, struct iatt *postparent) +{ +        inode_unlink (state->loc.inode, state->loc.parent, +                      state->loc.name); + +        forget_inode_if_no_dentry (state->loc.inode); + +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +} + +void +server_post_rmdir (server_state_t *state, gfs3_rmdir_rsp *rsp, +                    struct iatt *preparent, struct iatt *postparent) +{ +        inode_unlink (state->loc.inode, state->loc.parent, +                      state->loc.name); +        /* parent should not be found for directories after +         * inode_unlink, since directories cannot have +         * hardlinks. +         */ +        forget_inode_if_no_dentry (state->loc.inode); + +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); +} + +void +server_post_symlink (server_state_t *state, gfs3_symlink_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); +        inode_lookup (link_inode); +        inode_unref (link_inode); + +} + +void +server_post_link (server_state_t *state, gfs3_link_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc2.parent, +                                 state->loc2.name, stbuf); +        inode_lookup (link_inode); +        inode_unref (link_inode); + +} + +void +server_post_truncate (gfs3_truncate_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_writev (gfs3_write_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_statfs (gfs3_statfs_rsp *rsp, struct statvfs *stbuf) +{ +        gf_statfs_from_statfs (&rsp->statfs, stbuf); +} + +void +server_post_fsync (gfs3_fsync_rsp *rsp, struct iatt *prebuf, +                   struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_ftruncate (gfs3_ftruncate_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_fstat (gfs3_fstat_rsp *rsp, struct iatt *stbuf) +{ +        gf_stat_from_iatt (&rsp->stat, stbuf); +} + +void +server_post_lk (xlator_t *this, gfs3_lk_rsp *rsp, struct gf_flock *lock) +{ +        switch (lock->l_type) { +        case F_RDLCK: +                lock->l_type = GF_LK_F_RDLCK; +                break; +        case F_WRLCK: +                lock->l_type = GF_LK_F_WRLCK; +                break; +        case F_UNLCK: +                lock->l_type = GF_LK_F_UNLCK; +                break; +        default: +                gf_msg (this->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR, +                        "Unknown lock type: %"PRId32"!", lock->l_type); +                break; +        } + +        gf_proto_flock_from_flock (&rsp->flock, lock); +} + +int +server_post_readdir (gfs3_readdir_rsp *rsp, gf_dirent_t *entries) +{ +                int     ret = 0; + +                ret = serialize_rsp_dirent (entries, rsp); + +        return ret; +} +void +server_post_zerofill (gfs3_zerofill_rsp *rsp, struct iatt *statpre, +                      struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_discard (gfs3_discard_rsp *rsp, struct iatt *statpre, +                      struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_fallocate (gfs3_fallocate_rsp *rsp, struct iatt *statpre, +                       struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +int +server_post_readdirp (gfs3_readdirp_rsp *rsp, gf_dirent_t *entries) +{ +                int     ret = 0; + +                ret = serialize_rsp_direntp (entries, rsp); + +        return ret; +} + +void +server_post_fsetattr (gfs3_fsetattr_rsp *rsp, struct iatt *statpre, +                       struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_setattr (gfs3_setattr_rsp *rsp, struct iatt *statpre, +                     struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum, +                       uint8_t *strong_checksum) +{ +        rsp->weak_checksum = weak_checksum; + +        rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum; +        rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH; + +} + +void +server_post_rename (call_frame_t *frame, +                    server_state_t *state, gfs3_rename_rsp *rsp, +                    struct iatt *stbuf, +                    struct iatt *preoldparent, +                    struct iatt *postoldparent, +                    struct iatt *prenewparent, +                    struct iatt *postnewparent) +{ +        inode_t             *tmp_inode  = NULL; +        inode_t             *tmp_parent = NULL; + +        stbuf->ia_type = state->loc.inode->ia_type; + +        /* TODO: log gfid of the inodes */ +        gf_msg_trace (frame->root->client->bound_xl->name, 0, "%"PRId64": " +                      "RENAME_CBK %s ==> %s", frame->root->unique, +                      state->loc.name, state->loc2.name); + +        /* Before renaming the inode, we have to get the inode for the +         * destination entry (i.e. inode with state->loc2.parent as +         * parent and state->loc2.name as name). If it exists, then +         * unlink that inode, and send forget on that inode if the +         * unlinked entry is the last entry. In case of fuse client +         * the fuse kernel module itself sends the forget on the +         * unlinked inode. +         */ +        tmp_inode = inode_grep (state->loc.inode->table, +                                state->loc2.parent, state->loc2.name); +        if (tmp_inode) { +                inode_unlink (tmp_inode, state->loc2.parent, +                              state->loc2.name); +                forget_inode_if_no_dentry (tmp_inode); +                inode_unref (tmp_inode); +        } + +        inode_rename (state->itable, +                      state->loc.parent, state->loc.name, +                      state->loc2.parent, state->loc2.name, +                      state->loc.inode, stbuf); +        gf_stat_from_iatt (&rsp->stat, stbuf); + +        gf_stat_from_iatt (&rsp->preoldparent, preoldparent); +        gf_stat_from_iatt (&rsp->postoldparent, postoldparent); + +        gf_stat_from_iatt (&rsp->prenewparent, prenewparent); +        gf_stat_from_iatt (&rsp->postnewparent, postnewparent); + +} + +int +server_post_open (call_frame_t *frame, xlator_t *this, +                  gfs3_open_rsp *rsp, fd_t *fd) +{ +        server_ctx_t        *serv_ctx = NULL; +        uint64_t             fd_no    = 0; +        int                  ret       = 0; + +        serv_ctx = server_ctx_get (frame->root->client, this); +        if (serv_ctx == NULL) { +                gf_msg (this->name, GF_LOG_INFO, 0, +                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " +                        "failed"); +                return -1; +        } + +        fd_bind (fd); +        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); +        fd_ref (fd); +        rsp->fd = fd_no; + +        return 0; +} + +void +server_post_readv (gfs3_read_rsp *rsp, struct iatt *stbuf, int op_ret) +{ +        gf_stat_from_iatt (&rsp->stat, stbuf); +        rsp->size = op_ret; +} + +int +server_post_opendir (call_frame_t *frame, xlator_t *this, +                     gfs3_opendir_rsp *rsp, fd_t *fd) +{ +        server_ctx_t        *serv_ctx = NULL; +        uint64_t             fd_no    = 0; +        int                  ret       = 0; + +        serv_ctx = server_ctx_get (frame->root->client, this); +        if (serv_ctx == NULL) { +                gf_msg (this->name, GF_LOG_INFO, 0, +                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " +                        "failed"); +                return -1; +        } + +        fd_bind (fd); +        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); +        fd_ref (fd); +        rsp->fd = fd_no; + +        return 0; +} + +int +server_post_create (call_frame_t *frame, gfs3_create_rsp *rsp, +                    server_state_t *state, +                    xlator_t *this, fd_t *fd, inode_t *inode, +                    struct iatt *stbuf, struct iatt *preparent, +                    struct iatt *postparent) +{ +        server_ctx_t        *serv_ctx   = NULL; +        inode_t             *link_inode = NULL; +        uint64_t             fd_no      = 0; +        int                  op_errno   = 0; + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); + +        if (!link_inode) { +                op_errno = ENOENT; +                goto out; +        } + +        if (link_inode != inode) { +                /* +                  VERY racy code (if used anywhere else) +                  -- don't do this without understanding +                */ + +                inode_ctx_merge (fd, fd->inode, link_inode); +                inode_unref (fd->inode); +                fd->inode = inode_ref (link_inode); +        } + +        inode_lookup (link_inode); +        inode_unref (link_inode); + +        serv_ctx = server_ctx_get (frame->root->client, this); +        if (serv_ctx == NULL) { +                gf_msg (this->name, GF_LOG_INFO, 0, +                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " +                        "failed"); +                goto out; +        } + +        fd_bind (fd); +        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); +        fd_ref (fd); + +        if ((fd_no > UINT64_MAX) || (fd == 0)) { +                op_errno = errno; +        } + +        rsp->fd = fd_no; +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        return 0; +out: +        return -op_errno; +} + +/*TODO: Handle revalidate path */ +void +server_post_lookup (gfs3_lookup_rsp *rsp, call_frame_t *frame, +                    server_state_t *state, +                    inode_t *inode, struct iatt *stbuf, +                    struct iatt *postparent) +{ +        inode_t             *root_inode = NULL; +        inode_t             *link_inode = NULL; +        uuid_t               rootgfid   = {0,}; + +        root_inode = frame->root->client->bound_xl->itable->root; + +        if (inode == root_inode) { +                /* we just looked up root ("/") */ +                stbuf->ia_ino = 1; +                rootgfid[15]  = 1; +                gf_uuid_copy (stbuf->ia_gfid, rootgfid); +                if (inode->ia_type == 0) +                        inode->ia_type = stbuf->ia_type; +        } + +        gf_stat_from_iatt (&rsp->stat, stbuf); + +        if (!__is_root_gfid (inode->gfid)) { +                link_inode = inode_link (inode, state->loc.parent, +                                         state->loc.name, stbuf); +                if (link_inode) { +                        inode_lookup (link_inode); +                        inode_unref (link_inode); +                } +        } +} + +void +server_post_lease (gfs3_lease_rsp *rsp, struct gf_lease *lease) +{ +        gf_proto_lease_from_lease (&rsp->lease, lease); +}  | 
