diff options
Diffstat (limited to 'xlators/mount/fuse/src/fuse-helpers.c')
| -rw-r--r-- | xlators/mount/fuse/src/fuse-helpers.c | 300 | 
1 files changed, 300 insertions, 0 deletions
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c new file mode 100644 index 00000000000..d478d014db0 --- /dev/null +++ b/xlators/mount/fuse/src/fuse-helpers.c @@ -0,0 +1,300 @@ +/* +   Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#include "fuse-bridge.h" + +xlator_t * +fuse_state_subvol (fuse_state_t *state) +{ +        xlator_t *subvol = NULL; + +        if (!state) +                return NULL; + +        if (state->loc.inode) +                subvol = state->loc.inode->table->xl; + +        if (state->fd) +                subvol = state->fd->inode->table->xl; + +        return subvol; +} + + +xlator_t * +fuse_active_subvol (xlator_t *fuse) +{ +        fuse_private_t *priv = NULL; + +        priv = fuse->private; + +        return priv->active_subvol; +} + + + +static void +fuse_resolve_wipe (gf_resolve_t *resolve) +{ +        struct gf_resolve_comp *comp = NULL; + +        if (resolve->path) +                GF_FREE ((void *)resolve->path); + +        if (resolve->bname) +                GF_FREE ((void *)resolve->bname); + +        if (resolve->resolved) +                GF_FREE ((void *)resolve->resolved); + +        loc_wipe (&resolve->deep_loc); + +        comp = resolve->components; + +        if (comp) { +/* +                int                  i = 0; + +                for (i = 0; comp[i].basename; i++) { +                        if (comp[i].inode) +                                inode_unref (comp[i].inode); +                } +*/ +                GF_FREE ((void *)resolve->components); +        } +} + +void +free_fuse_state (fuse_state_t *state) +{ +        loc_wipe (&state->loc); + +        loc_wipe (&state->loc2); + +        if (state->dict) { +                dict_unref (state->dict); +                state->dict = (void *)0xaaaaeeee; +        } +        if (state->name) { +                GF_FREE (state->name); +                state->name = NULL; +        } +        if (state->fd) { +                fd_unref (state->fd); +                state->fd = (void *)0xfdfdfdfd; +        } +        if (state->finh) { +                GF_FREE (state->finh); +                state->finh = NULL; +        } + +        fuse_resolve_wipe (&state->resolve); +        fuse_resolve_wipe (&state->resolve2); + +#ifdef DEBUG +        memset (state, 0x90, sizeof (*state)); +#endif +        GF_FREE (state); +        state = NULL; +} + + +fuse_state_t * +get_fuse_state (xlator_t *this, fuse_in_header_t *finh) +{ +        fuse_state_t *state = NULL; + +        state = (void *)GF_CALLOC (1, sizeof (*state), +                                   gf_fuse_mt_fuse_state_t); +        if (!state) +                return NULL; +        state->pool = this->ctx->pool; +        state->finh = finh; +        state->this = this; + +        LOCK_INIT (&state->lock); + +        return state; +} + + +call_frame_t * +get_call_frame_for_req (fuse_state_t *state) +{ +        call_pool_t           *pool = NULL; +        fuse_in_header_t      *finh = NULL; +        call_frame_t          *frame = NULL; +        xlator_t              *this = NULL; + +        pool = state->pool; +        finh = state->finh; +        this = state->this; + +        frame = create_frame (this, pool); +        if (!frame) +                return NULL; + +        if (finh) { +                frame->root->uid      = finh->uid; +                frame->root->gid      = finh->gid; +                frame->root->pid      = finh->pid; +                frame->root->lk_owner = state->lk_owner; +                frame->root->unique   = finh->unique; +        } + +        frame->root->type = GF_OP_TYPE_FOP; + +        return frame; +} + + +inode_t * +fuse_ino_to_inode (uint64_t ino, xlator_t *fuse) +{ +        inode_t  *inode = NULL; +        xlator_t *active_subvol = NULL; + +        if (ino == 1) { +                active_subvol = fuse_active_subvol (fuse); +                inode = active_subvol->itable->root; +        } else { +                inode = (inode_t *) (unsigned long) ino; +                inode_ref (inode); +        } + +        return inode; +} + +uint64_t +inode_to_fuse_nodeid (inode_t *inode) +{ +        if (!inode || inode->ino == 1) +                return 1; + +        return (unsigned long) inode; +} + + +GF_MUST_CHECK int32_t +fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino, +               ino_t par, const char *name) +{ +        inode_t  *inode = NULL; +        inode_t  *parent = NULL; +        int32_t   ret = -1; +        char     *path = NULL; + +        /* resistance against multiple invocation of loc_fill not to get +           reference leaks via inode_search() */ + +        if (name) { +                parent = loc->parent; +                if (!parent) { +                        parent = fuse_ino_to_inode (par, state->this); +                        loc->parent = parent; +                } + +                inode = loc->inode; +                if (!inode) { +                        inode = inode_grep (parent->table, parent, name); +                        loc->inode = inode; +                } + +                ret = inode_path (parent, name, &path); +                if (ret <= 0) { +                        gf_log ("glusterfs-fuse", GF_LOG_DEBUG, +                                "inode_path failed for %"PRId64"/%s", +                                parent->ino, name); +                        goto fail; +                } +                loc->path = path; +        } else { +                inode = loc->inode; +                if (!inode) { +                        inode = fuse_ino_to_inode (ino, state->this); +                        loc->inode = inode; +                } + +                parent = loc->parent; +                if (!parent) { +                        parent = inode_parent (inode, par, name); +                        loc->parent = parent; +                } + +                ret = inode_path (inode, NULL, &path); +                if (ret <= 0) { +                        gf_log ("glusterfs-fuse", GF_LOG_DEBUG, +                                "inode_path failed for %"PRId64, +                                inode->ino); +                        goto fail; +                } +                loc->path = path; +        } + +        if (inode) +                loc->ino = inode->ino; + +        if (loc->path) { +                loc->name = strrchr (loc->path, '/'); +                if (loc->name) +                        loc->name++; +                else +                        loc->name = ""; +        } + +        if ((ino != 1) && (parent == NULL)) { +                gf_log ("fuse-bridge", GF_LOG_DEBUG, +                        "failed to search parent for %"PRId64"/%s (%"PRId64")", +                        (ino_t)par, name, (ino_t)ino); +                ret = -1; +                goto fail; +        } +        ret = 0; +fail: +        return ret; +} + + +/* courtesy of folly */ +void +gf_fuse_stat2attr (struct iatt *st, struct fuse_attr *fa) +{ +        fa->ino        = st->ia_ino; +        fa->size       = st->ia_size; +        fa->blocks     = st->ia_blocks; +        fa->atime      = st->ia_atime; +        fa->mtime      = st->ia_mtime; +        fa->ctime      = st->ia_ctime; +        fa->atimensec  = st->ia_atime_nsec; +        fa->mtimensec  = st->ia_mtime_nsec; +        fa->ctimensec  = st->ia_ctime_nsec; +        fa->mode       = st_mode_from_ia (st->ia_prot, st->ia_type); +        fa->nlink      = st->ia_nlink; +        fa->uid        = st->ia_uid; +        fa->gid        = st->ia_gid; +        fa->rdev       = st->ia_rdev; +#if FUSE_KERNEL_MINOR_VERSION >= 9 +        fa->blksize    = st->ia_blksize; +#endif +#ifdef GF_DARWIN_HOST_OS +        fa->crtime     = (uint64_t)-1; +        fa->crtimensec = (uint32_t)-1; +        fa->flags      = 0; +#endif +}  | 
