diff options
| author | Amar Tumballi <amarts@redhat.com> | 2012-07-12 22:59:04 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2012-07-12 16:16:35 -0700 | 
| commit | 89bd58e170118e4d534e6113c1c368c1a39cc919 (patch) | |
| tree | 9f8b7e235b9821191394735305739f65d3c17324 | |
| parent | ac6be8b4204330d117d24e1473becda3f3989cb1 (diff) | |
core: remove the unused files - round 2
BUG: 764890
Change-Id: I3eb626eeaa2a09f0e248444f560c2a0eaf46c642
Signed-off-by: Amar Tumballi <amarts@redhat.com>
Reviewed-on: http://review.gluster.com/3660
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
40 files changed, 0 insertions, 19881 deletions
diff --git a/doc/glusterfs.vol.sample b/doc/glusterfs.vol.sample deleted file mode 100644 index 977363b921b..00000000000 --- a/doc/glusterfs.vol.sample +++ /dev/null @@ -1,53 +0,0 @@ -### file: client-volume.vol.sample - -##################################### -###  GlusterFS Client Volume File  ## -##################################### - -#### CONFIG FILE RULES: -### "#" is comment character. -### - Config file is case sensitive -### - Options within a volume block can be in any order. -### - Spaces or tabs are used as delimitter within a line. -### - Each option should end within a line. -### - Missing or commented fields will assume default values. -### - Blank/commented lines are allowed. -### - Sub-volumes should already be defined above before referring. - -### Add client feature and attach to remote subvolume -volume client -  type protocol/client -  option transport-type tcp -# option transport-type unix -# option transport-type ib-sdp -  option remote-host 127.0.0.1         # IP address of the remote brick -# option transport.socket.remote-port 24016 - -# option transport-type rdma -# option transport.rdma.remote-port 24016 -# option transport.rdma.work-request-send-count 16 -# option transport.rdma.work-request-recv-count 16 - -  option remote-subvolume brick        # name of the remote volume -end-volume - -### Add readahead feature -#volume readahead -#  type performance/read-ahead -#  option page-count 2       # cache per file  = (page-count x page-size) -#  subvolumes client -#end-volume - -### Add IO-Cache feature -#volume iocache -#  type performance/io-cache -#  subvolumes readahead -#end-volume - -### Add writeback feature -#volume writeback -#  type performance/write-behind -#  option window-size 2MB -#  option flush-behind off -#  subvolumes iocache -#end-volume diff --git a/doc/glusterfsd.vol.sample b/doc/glusterfsd.vol.sample deleted file mode 100644 index ec2fd341ef0..00000000000 --- a/doc/glusterfsd.vol.sample +++ /dev/null @@ -1,44 +0,0 @@ -### file: server-volume.vol.sample - -##################################### -###  GlusterFS Server Volume File  ## -##################################### - -#### CONFIG FILE RULES: -### "#" is comment character. -### - Config file is case sensitive -### - Options within a volume block can be in any order. -### - Spaces or tabs are used as delimitter within a line. -### - Multiple values to options will be : delimited. -### - Each option should end within a line. -### - Missing or commented fields will assume default values. -### - Blank/commented lines are allowed. -### - Sub-volumes should already be defined above before referring. - -### Export volume "brick" with the contents of "/home/export" directory. -volume brick -  type storage/posix                   # POSIX FS translator -  option directory /home/export        # Export this directory -end-volume - -### Add network serving capability to above brick. -volume server -  type protocol/server -  option transport-type tcp -# option transport-type unix -# option transport-type ib-sdp -# option transport.socket.bind-address 192.168.1.10     # Default is to listen -                                                        # on all interfaces -# option transport.socket.listen-port 24016 - -# option transport-type rdma -# option transport.rdma.listen-port 24016 -# option transport.rdma.work-request-send-count 64 -# option transport.rdma.work-request-recv-count 64 - -  subvolumes brick -# NOTE: Access to any volume through protocol/server is denied by -# default. You need to explicitly grant access through # "auth" -# option. -  option auth.addr.brick.allow * # Allow access to "brick" volume -end-volume diff --git a/libglusterfsclient/Makefile.am b/libglusterfsclient/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/libglusterfsclient/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/libglusterfsclient/src/Makefile.am b/libglusterfsclient/src/Makefile.am deleted file mode 100644 index 32811c0d5bf..00000000000 --- a/libglusterfsclient/src/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -lib_LTLIBRARIES = libglusterfsclient.la -noinst_HEADERS = libglusterfsclient-internals.h -libglusterfsclient_HEADERS = libglusterfsclient.h  -libglusterfsclientdir = $(includedir) - -libglusterfsclient_la_SOURCES = libglusterfsclient.c libglusterfsclient-dentry.c -libglusterfsclient_la_CFLAGS =  -fPIC -Wall -libglusterfsclient_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -libglusterfsclient_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D$(GF_HOST_OS) -D__USE_FILE_OFFSET64 -D_GNU_SOURCE -I$(top_srcdir)/libglusterfs/src -DDATADIR=\"$(localstatedir)\" -DCONFDIR=\"$(sysconfdir)/glusterfs\" $(GF_CFLAGS) -libglusterfsclient_la_LDFLAGS = -shared -nostartfiles - -CLEANFILES =  - -$(top_builddir)/libglusterfs/src/libglusterfs.la: -	$(MAKE) -C $(top_builddir)/libglusterfs/src/ all - diff --git a/libglusterfsclient/src/libglusterfsclient-dentry.c b/libglusterfsclient/src/libglusterfsclient-dentry.c deleted file mode 100644 index 3fa5f6e1e74..00000000000 --- a/libglusterfsclient/src/libglusterfsclient-dentry.c +++ /dev/null @@ -1,404 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#include "libglusterfsclient.h" -#include "libglusterfsclient-internals.h" -#include <libgen.h> - -#define LIBGLUSTERFS_CLIENT_DENTRY_LOC_PREPARE(_new_loc, _loc, _parent, \ -                                               _resolved) do {          \ -                size_t pathlen = 0;                                     \ -                size_t resolvedlen = 0;                                 \ -                char *path = NULL;                                      \ -                int pad = 0;                                            \ -                pathlen   = strlen (_loc->path) + 1;                    \ -                path = CALLOC (1, pathlen);                             \ -                _new_loc.parent =  _parent;                             \ -                resolvedlen = strlen (_resolved);                       \ -                strncpy (path, _resolved, resolvedlen);                 \ -                if (resolvedlen == 1) /* only root resolved */          \ -                        pad = 0;                                        \ -                else {                                                  \ -                        pad = 1;                                        \ -                        path[resolvedlen] = '/';                        \ -                }                                                       \ -                strcpy_till (path + resolvedlen + pad,                  \ -                             loc->path + resolvedlen + pad, '/');       \ -                _new_loc.path = path;                                   \ -                _new_loc.name = strrchr (path, '/');                    \ -                if (_new_loc.name)                                      \ -                        _new_loc.name++;                                \ -        }while (0); - - -/* strcpy_till - copy @dname to @dest, until 'delim' is encountered in @dest - * @dest - destination string - * @dname - source string - * @delim - delimiter character - * - * return - NULL is returned if '0' is encountered in @dname, otherwise returns - *          a pointer to remaining string begining in @dest. - */ -static char * -strcpy_till (char *dest, const char *dname, char delim) -{ -        char *src = NULL; -        int idx = 0; -        char *ret = NULL; - -        src = (char *)dname; -        while (src[idx] && (src[idx] != delim)) { -                dest[idx] = src[idx]; -                idx++; -        } - -        dest[idx] = 0; - -        if (src[idx] == 0) -                ret = NULL; -        else -                ret = &(src[idx]); - -        return ret; -} - -/* __libgf_client_path_to_parenti - derive parent inode for @path. if immediate  - *                            parent is not available in the dentry cache, return nearest - *                            available parent inode and set @reslv to the path of - *                            the returned directory. - * - * @itable - inode table - * @path   - path whose parent has to be looked up. - * @reslv  - if immediate parent is not available, reslv will be set to path of the - *           resolved parent. - * - * return - should never return NULL. should at least return '/' inode. - */ -static inode_t * -__libgf_client_path_to_parenti (libglusterfs_client_ctx_t *ctx, -                                inode_table_t *itable, const char *path, -                                char **reslv) -{ -        char *resolved_till = NULL; -        char *strtokptr = NULL; -        char *component = NULL; -        char *next_component = NULL; -        char *pathdup = NULL; -        inode_t *curr = NULL; -        inode_t *parent = NULL; -        size_t pathlen = 0; -        loc_t rootloc = {0, }; -        int ret = -1; - -        pathlen = STRLEN_0 (path); -        resolved_till = CALLOC (1, pathlen); - -        GF_VALIDATE_OR_GOTO("libglusterfsclient-dentry", resolved_till, out); -        pathdup = strdup (path); -        GF_VALIDATE_OR_GOTO("libglusterfsclient-dentry", pathdup, out); - -        parent = inode_ref (itable->root); -        /* If the root inode's is outdated, send a revalidate on it. -         * A revalidate on root inode also reduces the window in which an -         * op will fail over distribute because the layout of the root -         * directory did not  get constructed when we sent the lookup on -         * root in glusterfs_init. That can happen when not all children of a -         * distribute volume were up at the time of glusterfs_init. -         */ -        if (!libgf_is_iattr_cache_valid (ctx, parent, NULL, -                                        LIBGF_VALIDATE_LOOKUP)) { -                libgf_client_loc_fill (&rootloc, ctx, 1, 0, "/"); -                ret = libgf_client_lookup (ctx, &rootloc, NULL, NULL, NULL); -                if (ret == -1) { -                        gf_log ("libglusterfsclient-dentry", GF_LOG_ERROR, -                                "Root inode revalidation failed"); -                        inode_unref (parent); -                        parent = NULL; -                        goto out; -                } -                libgf_client_loc_wipe (&rootloc); -        } - -        curr = NULL; - -        component = strtok_r (pathdup, "/", &strtokptr); - -        while (component) { -                curr = inode_search (itable, parent->ino, component); -                if (!curr) { -                        break; -                } -                if (!libgf_is_iattr_cache_valid (ctx, curr, NULL, -                                                LIBGF_VALIDATE_LOOKUP)) -                        break; - -                /* It is OK to append the component even if it is the        -                   last component in the path, because, if 'next_component' -                   returns NULL, @parent will remain the same and -                   @resolved_till will not be sent back                -                */ -                strcat (resolved_till, "/"); -                strcat (resolved_till, component); - -                next_component = strtok_r (NULL, "/", &strtokptr); - -                if (next_component) { -                        inode_unref (parent); -                        parent = curr; -                        curr = NULL; -                } else { -                        /* will break */ -                        inode_unref (curr); -                } - -                component = next_component; -        } - -        if (resolved_till[0] == '\0') { -                strcat (resolved_till, "/"); -        } - -        free (pathdup); -         -        if (reslv) { -                *reslv = resolved_till; -        } else { -                FREE (resolved_till); -        } - -out: -        return parent; -} - -static inline void -libgf_client_update_resolved (const char *path, char *resolved) -{ -        int32_t pathlen = 0; -        char *tmp = NULL, *dest = NULL, *dname = NULL; -        char append_slash = 0; - -        pathlen = strlen (resolved);  -        tmp = (char *)(resolved + pathlen); -        if (*((char *) (resolved + pathlen - 1)) != '/') { -                tmp[0] = '/'; -                append_slash = 1; -        } - -        if (append_slash) { -                dest = tmp + 1; -        } else { -                dest = tmp; -        } - -        if (*((char *) path + pathlen) == '/') { -                dname = (char *) path + pathlen + 1; -        } else { -                dname = (char *) path + pathlen; -        } - -        strcpy_till (dest, dname, '/'); -} - -/* __do_path_resolve - resolve @loc->path into @loc->inode and @loc->parent. also - *                     update the dentry cache - * - * @loc             - loc to resolve.  - * @ctx             - libglusterfsclient context - * @lookup_basename - flag whether to lookup basename(loc->path) - * - * return - 0 on success - *         -1 on failure  - *           - */ -static int32_t -__do_path_resolve (loc_t *loc, libglusterfs_client_ctx_t *ctx, -                   char lookup_basename) -{ -        int32_t         op_ret = -1; -        char           *resolved  = NULL; -        inode_t        *parent = NULL, *inode = NULL; -        dentry_t       *dentry = NULL; -        loc_t          new_loc = {0, }; -	char           *pathname = NULL, *directory = NULL; -	char           *file = NULL;    -         -        parent = loc->parent; -        if (parent) { -                inode_ref (parent); -                gf_log ("libglusterfsclient-dentry", GF_LOG_DEBUG, -                        "loc->parent(%"PRId64") already present. sending " -                        "lookup for %"PRId64"/%s", parent->ino, parent->ino, -                        loc->path); -                resolved = strdup (loc->path); -                resolved = dirname (resolved); -        } else { -                parent = __libgf_client_path_to_parenti (ctx, ctx->itable, -                                                         loc->path, &resolved); -        } - -        if (parent == NULL) { -                /* fire in the bush.. run! run!! run!!! */ -                gf_log ("libglusterfsclient-dentry", -                        GF_LOG_CRITICAL, -                        "failed to get parent inode number"); -                op_ret = -1; -                goto out; -        }                - -        gf_log ("libglusterfsclient-dentry", -                GF_LOG_DEBUG, -                "resolved path(%s) till %"PRId64"(%s). " -                "sending lookup for remaining path", -                loc->path, parent->ino, resolved); - -	pathname = strdup (loc->path); -	directory = dirname (pathname); -        pathname = NULL; - -        while (strcmp (resolved, directory) != 0)  -        { -                dentry = NULL; - -                LIBGLUSTERFS_CLIENT_DENTRY_LOC_PREPARE (new_loc, loc, parent, -                                                        resolved); - -		if (pathname) { -			free (pathname); -			pathname = NULL; -		} - -		pathname = strdup (new_loc.path); -		file = basename (pathname); - -                new_loc.inode = inode_search (ctx->itable, parent->ino, file); -                if (new_loc.inode) { -                        if (libgf_is_iattr_cache_valid (ctx, new_loc.inode, -                                                        NULL, -                                                        LIBGF_VALIDATE_LOOKUP)) -                                dentry = dentry_search_for_inode (new_loc.inode, -                                                                  parent->ino, -                                                                  file); -                } - -                if (dentry == NULL) { -                        op_ret = libgf_client_lookup (ctx, &new_loc, NULL, NULL, -                                                      0); -                        if (op_ret == -1) { -                                inode_ref (new_loc.parent); -                                libgf_client_loc_wipe (&new_loc); -                                goto out; -                        } -                } - -                parent = inode_ref (new_loc.inode); -                libgf_client_loc_wipe (&new_loc); - -                libgf_client_update_resolved (loc->path, resolved); -        } - -	if (pathname) { -		free (pathname); -		pathname = NULL; -	}  - -        if (lookup_basename) { -                pathname = strdup (loc->path); -                file = basename (pathname); - -                inode = inode_search (ctx->itable, parent->ino, file); -                if (!inode) { -                        libgf_client_loc_fill (&new_loc, ctx, 0, parent->ino, -                                               file); - -                        op_ret = libgf_client_lookup (ctx, &new_loc, NULL, NULL, -                                                      0); -                        if (op_ret == -1) { -                                libgf_client_loc_wipe (&new_loc); -                                goto out; -                        } -                 -                        inode = inode_ref (new_loc.inode); -                        libgf_client_loc_wipe (&new_loc); -                } -        } - -        op_ret = 0; -out: -        loc->inode = inode; -        loc->parent = parent; - -        FREE (resolved); -	if (pathname) { -		FREE (pathname); -	} - -	if (directory) { -		FREE (directory); -	} - -        return op_ret; -} - - -/* resolves loc->path to loc->parent and loc->inode */ -int32_t -libgf_client_path_lookup (loc_t *loc, -                          libglusterfs_client_ctx_t *ctx, -                          char lookup_basename) -{ -        char       *pathname  = NULL; -        char       *directory = NULL; -        inode_t    *inode = NULL; -        inode_t    *parent = NULL; -        int32_t     op_ret = 0; - -        pathname  = strdup (loc->path); -        directory = dirname (pathname); -        parent = inode_from_path (ctx->itable, directory); - -        if (parent != NULL) { -                loc->parent = parent; - -                if (!lookup_basename) { -                        gf_log ("libglusterfsclient", -                                GF_LOG_DEBUG, -                                "resolved dirname(%s) to %"PRId64, -                                loc->path, parent->ino); -                        goto out; -                } else { -                        inode = inode_from_path (ctx->itable, loc->path); -                        if (inode != NULL) { -                                gf_log ("libglusterfsclient", -                                        GF_LOG_DEBUG, -                                        "resolved path(%s) to %"PRId64"/%"PRId64, -                                        loc->path, parent->ino, inode->ino); -                                loc->inode = inode; -                                goto out; -                        } -                } -        } - -        if (parent) { -                inode_unref (parent); -        } else if (inode) { -                inode_unref (inode); -                gf_log ("libglusterfsclient", -                        GF_LOG_ERROR, -                        "undesired behaviour. inode(%"PRId64") for %s " -                        "exists without parent (%s)", -                        inode->ino, loc->path, directory); -        } -        op_ret = __do_path_resolve (loc, ctx, lookup_basename); -out:     -        if (pathname) -                free (pathname); - -        return op_ret; -} diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h deleted file mode 100755 index 7b62ce8efbf..00000000000 --- a/libglusterfsclient/src/libglusterfsclient-internals.h +++ /dev/null @@ -1,289 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef __LIBGLUSTERFSCLIENT_INTERNALS_H -#define __LIBGLUSTERFSCLIENT_INTERNALS_H - -#include <glusterfs.h> -#include <logging.h> -#include <inode.h> -#include <pthread.h> -#include <stack.h> -#include <list.h> -#include <signal.h> -#include <call-stub.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <fd.h> -#include <dirent.h> - -#define LIBGF_IOBUF_SIZE        (128 *GF_UNIT_KB) -typedef void (*sighandler_t) (int); -typedef struct list_head list_head_t; - -typedef struct libglusterfs_client_ctx { -        glusterfs_ctx_t gf_ctx; -        inode_table_t *itable; -        pthread_t reply_thread; -        call_pool_t pool; -        uint32_t counter; -        time_t lookup_timeout; -        time_t stat_timeout; -        /* We generate a fake fsid for the subvolume being -         * accessed through this context. -         */ -        dev_t fake_fsid; -        pid_t pid; -}libglusterfs_client_ctx_t; - -typedef struct signal_handler { -        int signo; -        sighandler_t handler; -        list_head_t next; -}libgf_client_signal_handler_t ; - -typedef struct { -        pthread_mutex_t lock; -        pthread_cond_t reply_cond; -        call_stub_t *reply_stub; -        char complete; -        union { -                struct { -                        char is_revalidate; -                        loc_t *loc; -                        int32_t size; -                } lookup; -        }fop; -        fd_t *fd;          /* Needed here because we need a ref to the dir -                              fd in the libgf_client_readdir_cbk in order -                              to process the dirents received, without -                              having them added to the reply stub. -                              Also used in updating iattr cache. See -                              readv_cbk for eg. -                              */ -}libgf_client_local_t; - -typedef struct { -        pthread_cond_t init_con_established; -        pthread_mutex_t lock; -        char complete; -}libglusterfs_client_private_t; - -typedef struct { -        pthread_mutex_t lock; -        uint32_t previous_lookup_time; -        uint32_t previous_stat_time; -        struct iatt stbuf; -} libglusterfs_client_inode_ctx_t; - -/* Our dirent cache is very simplistic when it comes to directory - * reading workloads. It assumes that all directory traversal operations happen - * sequentially and that readdir callers dont go jumping around the directory - * using seekdir, rewinddir. Thats why you'll notice that seekdir, rewinddir - * API in libglusterfsclient only set the offset. The consequence is that when - * libgf_dcache_readdir finds that the offset presented to it, is not - * the same as the offset of the previous dirent returned by dcache (..stored - * in struct direntcache->prev_off..), it realises that a non-sequential - * directory read is in progress and returns 0 to signify that the cache is - * not valid. - * This could be made a bit more intelligent by using a data structure like - * a hash-table or a balanced binary tree that allows us to search for the - * existence of particular offsets in the cache without performing a list or - * array traversal. - * Dont use a simple binary search tree because - * there is no guarantee that offsets in a sequential reading of the directory - * will be just random integers. If for some reason they are sequential, a BST - * will end up becoming a list. - */ -struct direntcache { -        gf_dirent_t entries;            /* Head of list of cached dirents. */ -        gf_dirent_t *next;              /* Pointer to the next entry that -                                         * should be sent by readdir */ -        uint64_t prev_off;              /* Offset where the next read will -                                         * happen. -                                         */ -}; - -typedef struct { -        pthread_mutex_t lock; -        off_t offset; -        libglusterfs_client_ctx_t *ctx; -        /* `man readdir` says readdir is non-re-entrant -         * only if two readdirs are racing on the same -         * handle. -         */ -	struct dirent dirp; -        struct direntcache *dcache; -        char   vpath[PATH_MAX];  -} libglusterfs_client_fd_ctx_t; - -typedef struct libglusterfs_client_async_local { -        void *cbk_data; -        union { -                struct { -                        fd_t *fd; -                        glusterfs_readv_cbk_t cbk; -                        char update_offset; -                }readv_cbk; -     -                struct { -                        fd_t *fd; -                        glusterfs_write_cbk_t cbk; -                }write_cbk; - -                struct { -                        fd_t *fd; -                }close_cbk; - -                struct { -                        void *buf; -                        size_t size; -                        loc_t *loc; -                        char is_revalidate; -                        glusterfs_get_cbk_t cbk; -                }lookup_cbk; -        }fop; -}libglusterfs_client_async_local_t; - -#define LIBGF_STACK_WIND_AND_WAIT(frame, rfn, obj, fn, params ...)      \ -        do {                                                            \ -                STACK_WIND (frame, rfn, obj, fn, params);               \ -                pthread_mutex_lock (&local->lock);                      \ -                {                                                       \ -                        while (!local->complete) {                      \ -                                pthread_cond_wait (&local->reply_cond,  \ -                                                   &local->lock);       \ -                        }                                               \ -                }                                                       \ -                pthread_mutex_unlock (&local->lock);                    \ -        } while (0) - - -#define LIBGF_CLIENT_SIGNAL(signal_handler_list, signo, handler)        \ -        do {                                                            \ -                libgf_client_signal_handler_t *libgf_handler = CALLOC (1, \ -                                                    sizeof (*libgf_handler)); \ -                ERR_ABORT (libgf_handler);                              \ -                libgf_handler->signo = signo;                           \ -                libgf_handler->handler = signal (signo, handler);       \ -                list_add (&libgf_handler->next, signal_handler_list);   \ -        } while (0)                                                            - -#define LIBGF_INSTALL_SIGNAL_HANDLERS(signal_handlers)                  \ -        do {                                                            \ -                INIT_LIST_HEAD (&signal_handlers);                      \ -                /* Handle SIGABORT and SIGSEGV */                       \ -                LIBGF_CLIENT_SIGNAL (&signal_handlers, SIGSEGV, gf_print_trace); \ -                LIBGF_CLIENT_SIGNAL (&signal_handlers, SIGABRT, gf_print_trace); \ -                LIBGF_CLIENT_SIGNAL (&signal_handlers, SIGHUP, gf_log_logrotate); \ -                /* LIBGF_CLIENT_SIGNAL (SIGTERM, glusterfs_cleanup_and_exit); */ \ -        } while (0) - -#define LIBGF_RESTORE_SIGNAL_HANDLERS(local)                            \ -        do {                                                            \ -                libgf_client_signal_handler_t *ptr = NULL, *tmp = NULL; \ -                list_for_each_entry_safe (ptr, tmp, &local->signal_handlers,\ -                                          next) {                       \ -                        signal (ptr->signo, ptr->handler);              \ -                        FREE (ptr);                                     \ -                }                                                       \ -        } while (0)                                        - -#define LIBGF_CLIENT_FOP_ASYNC(ctx, local, ret_fn, op, args ...)        \ -        do {                                                            \ -                call_frame_t *frame = get_call_frame_for_req (ctx, 1);  \ -                xlator_t *xl = frame->this->children ?                  \ -                        frame->this->children->xlator : NULL;           \ -                frame->root->state = ctx;                               \ -                frame->local = local;                                   \ -                STACK_WIND (frame, ret_fn, xl, xl->fops->op, args);     \ -        } while (0) - -#define LIBGF_CLIENT_FOP(ctx, stub, op, local, args ...)                \ -        do {                                                            \ -                call_frame_t *frame = get_call_frame_for_req (ctx, 1);  \ -                xlator_t *xl = frame->this->children ?                  \ -                        frame->this->children->xlator : NULL;           \ -                if (!local) {                                           \ -                        local = CALLOC (1, sizeof (*local));            \ -                }                                                       \ -                ERR_ABORT (local);                                      \ -                frame->local = local;                                   \ -                frame->root->state = ctx;                               \ -                pthread_cond_init (&local->reply_cond, NULL);           \ -                pthread_mutex_init (&local->lock, NULL);                \ -                LIBGF_STACK_WIND_AND_WAIT (frame, libgf_client_##op##_cbk, xl, \ -                                           xl->fops->op, args);         \ -                stub = local->reply_stub;                               \ -                FREE (frame->local);                                    \ -                frame->local = NULL;                                    \ -                STACK_DESTROY (frame->root);                            \ -        } while (0) - -#define LIBGF_REPLY_NOTIFY(local)                                       \ -        do {                                                            \ -                pthread_mutex_lock (&local->lock);                      \ -                {                                                       \ -                        local->complete = 1;                            \ -                        pthread_cond_broadcast (&local->reply_cond);    \ -                }                                                       \ -                pthread_mutex_unlock (&local->lock);                    \ -        } while (0) - - -void -libgf_client_loc_wipe (loc_t *loc); - -int32_t -libgf_client_loc_fill (loc_t *loc, -                       libglusterfs_client_ctx_t *ctx, -                       ino_t ino, -                       ino_t par, -                       const char *name); - -int32_t -libgf_client_path_lookup (loc_t *loc, -                          libglusterfs_client_ctx_t *ctx, -                          char lookup_basename); - -int32_t -libgf_client_lookup (libglusterfs_client_ctx_t *ctx, -                     loc_t *loc, -                     struct iatt *stbuf, -                     dict_t **dict, -                     dict_t *xattr_req); - -/* We're not expecting more than 10-15 - * VMPs per process so a list is acceptable. - */ -struct vmp_entry { -        struct list_head list; -        char * vmp; -        int vmplen; -        glusterfs_handle_t handle; -}; - -#define LIBGF_UPDATE_LOOKUP     0x1 -#define LIBGF_UPDATE_STAT       0x2 -#define LIBGF_UPDATE_ALL        (LIBGF_UPDATE_LOOKUP | LIBGF_UPDATE_STAT) - -#define LIBGF_VALIDATE_LOOKUP  0x1 -#define LIBGF_VALIDATE_STAT     0x2 - -#define LIBGF_INVALIDATE_LOOKUP  0x1 -#define LIBGF_INVALIDATE_STAT     0x2 -int -libgf_is_iattr_cache_valid (libglusterfs_client_ctx_t *ctx, inode_t *inode, -                            struct iatt *sbuf, int flags); - -int -libgf_update_iattr_cache (inode_t *inode, int flags, struct iatt *buf); - -#endif diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c deleted file mode 100755 index 3881ad64296..00000000000 --- a/libglusterfsclient/src/libglusterfsclient.c +++ /dev/null @@ -1,8161 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <stdio.h> -#include <errno.h> -#include <libgen.h> -#include <stddef.h> - -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#ifdef GF_SOLARIS_HOST_OS -#include <sys/statfs.h> -#endif -#include <unistd.h> -#include <xlator.h> -#include <timer.h> -#include "defaults.h" -#include <time.h> -#include <poll.h> -#include "transport.h" -#include "event.h" -#include "libglusterfsclient.h" -#include "libglusterfsclient-internals.h" -#include "compat.h" -#include "compat-errno.h" -#ifndef GF_SOLARIS_HOST_OS -#include <sys/vfs.h> -#endif -#include <utime.h> -#include <sys/param.h> -#include <list.h> -#include <stdarg.h> -#include <sys/statvfs.h> -#include "hashfn.h" -#include <sys/select.h> - -#define LIBGF_XL_NAME "libglusterfsclient" -#define LIBGLUSTERFS_INODE_TABLE_LRU_LIMIT 1000 //14057 -#define LIBGF_SENDFILE_BLOCK_SIZE 4096 -#define LIBGF_READDIR_BLOCK     4096 -#define libgf_path_absolute(path) ((path)[0] == '/') - -static inline xlator_t * -libglusterfs_graph (xlator_t *graph); -int32_t libgf_client_readlink (libglusterfs_client_ctx_t *ctx, loc_t *loc, -                                        char *buf, size_t bufsize); - -int -libgf_realpath_loc_fill (libglusterfs_client_ctx_t *ctx, char *link, -                         loc_t *targetloc); -static int first_init = 1; - -/* The global list of virtual mount points */ -struct { -        struct list_head list; -        int              entries; -}vmplist; - - -/* Protects the VMP list above. */ -pthread_mutex_t vmplock = PTHREAD_MUTEX_INITIALIZER; - -/* Ensures only one thread is ever calling glusterfs_mount. - * Since that function internally calls routines which - * use the yacc parser code using global vars, this process - * needs to be syncronised. - */ -pthread_mutex_t mountlock = PTHREAD_MUTEX_INITIALIZER; - -static char cwd[PATH_MAX]; -static char cwd_inited = 0; -static pthread_mutex_t cwdlock   = PTHREAD_MUTEX_INITIALIZER; - -char * -libgf_vmp_virtual_path (struct vmp_entry *entry, const char *path, char *vpath) -{ -        char    *tmp = NULL; - -        tmp = ((char *)(path + (entry->vmplen-1))); -        if (strlen (tmp) > 0) { -                if (tmp[0] != '/') { -                        vpath[0] = '/'; -                        vpath[1] = '\0'; -                        strcat (&vpath[1], tmp); -                } else -                        strcpy (vpath, tmp); -        } else { -                vpath[0] = '/'; -                vpath[1] = '\0'; -        } - -        return vpath; -} - -char * -zr_build_process_uuid () -{ -	char           tmp_str[1024] = {0,}; -	char           hostname[256] = {0,}; -	struct timeval tv = {0,}; -	char           now_str[32]; - -	if (-1 == gettimeofday(&tv, NULL)) { -		gf_log ("", GF_LOG_ERROR,  -			"gettimeofday: failed %s", -			strerror (errno));		 -	} - -	if (-1 == gethostname (hostname, 256)) { -		gf_log ("", GF_LOG_ERROR,  -			"gethostname: failed %s", -			strerror (errno)); -	} - -        gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T); -	snprintf (tmp_str, sizeof tmp_str, "%s-%d-%s:%ld",  -		  hostname, getpid(), now_str, tv.tv_usec); -	 -	return strdup (tmp_str); -} - - -int32_t -libgf_client_forget (xlator_t *this, -		     inode_t *inode) -{ -        uint64_t ptr = 0; -	libglusterfs_client_inode_ctx_t *ctx = NULL; -	 -	inode_ctx_del (inode, this, &ptr); -        ctx = (libglusterfs_client_inode_ctx_t *)(long) ptr; - -	FREE (ctx); - -        return 0; -} - -xlator_t * -libgf_inode_to_xlator (inode_t *inode) -{ -        if (!inode) -                return NULL; - -        if (!inode->table) -                return NULL; - -        if (!inode->table->xl) -                return NULL; - -        if (!inode->table->xl->ctx) -                return NULL; - -        return inode->table->xl->ctx->top; -} - -libglusterfs_client_fd_ctx_t * -libgf_get_fd_ctx (fd_t *fd) -{ -        uint64_t                        ctxaddr = 0; -        libglusterfs_client_fd_ctx_t    *ctx = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); - -        if (fd_ctx_get (fd, libgf_inode_to_xlator (fd->inode), &ctxaddr) == -1) -                goto out; - -        ctx = (libglusterfs_client_fd_ctx_t *)(long)ctxaddr; - -out: -        return ctx; -} - -libglusterfs_client_fd_ctx_t * -libgf_alloc_fd_ctx (libglusterfs_client_ctx_t *ctx, fd_t *fd, char *vpath) -{ -        libglusterfs_client_fd_ctx_t    *fdctx = NULL; -        uint64_t                        ctxaddr = 0; - -        fdctx = CALLOC (1, sizeof (*fdctx)); -        if (fdctx == NULL) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, -                        "memory allocation failure"); -                fdctx = NULL; -                goto out; -        } - -        pthread_mutex_init (&fdctx->lock, NULL); -        fdctx->ctx = ctx; -        ctxaddr = (uint64_t) (long)fdctx; - -        if (fd->inode) { -                if (IA_ISDIR (fd->inode->ia_type)) { -                        fdctx->dcache = CALLOC (1, sizeof (struct direntcache)); -                        if (fdctx->dcache) -                                INIT_LIST_HEAD (&fdctx->dcache->entries.list); -                        /* If the calloc fails, we can still continue -                         * working as the dcache is not required for correct -                         * operation. -                         */ -                } -        } - -        if (vpath != NULL) { -                strcpy (fdctx->vpath, vpath); -                assert (strlen(vpath) > 0); -                if (vpath[strlen(vpath) - 1] != '/') { -                        strcat (fdctx->vpath, "/"); -                } -        } - -        fd_ctx_set (fd, libgf_inode_to_xlator (fd->inode), ctxaddr); -out: -        return fdctx; -} - -libglusterfs_client_fd_ctx_t * -libgf_del_fd_ctx (fd_t *fd) -{ -        uint64_t                        ctxaddr = 0; -        libglusterfs_client_fd_ctx_t    *ctx = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); - -        if (fd_ctx_del (fd, libgf_inode_to_xlator (fd->inode) , &ctxaddr) == -1) -                goto out; - -        ctx = (libglusterfs_client_fd_ctx_t *)(long)ctxaddr; - -out: -        return ctx; -} - -void -libgf_dcache_invalidate (fd_t *fd) -{ -        libglusterfs_client_fd_ctx_t    *fd_ctx = NULL; - -        if (!fd) -                return; - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                return; -        } - -        if (!fd_ctx->dcache) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No dcache present"); -                return; -        } - -        if (!list_empty (&fd_ctx->dcache->entries.list)) -                gf_dirent_free (&fd_ctx->dcache->entries); - -        INIT_LIST_HEAD (&fd_ctx->dcache->entries.list); - -        fd_ctx->dcache->next = NULL; -        fd_ctx->dcache->prev_off = 0; - -        return; -} - -/* The first entry in the entries is always a placeholder - * or the list head. The real entries begin from entries->next. - */ -int -libgf_dcache_update (libglusterfs_client_ctx_t *ctx, fd_t *fd, -                     gf_dirent_t *entries) -{ -        libglusterfs_client_fd_ctx_t    *fd_ctx = NULL; -        int                             op_ret = -1; - -        if ((!ctx) || (!fd) || (!entries)) { -                errno = EINVAL; -                goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -		goto out; -        } - -        /* dcache is not enabled. */ -        if (!fd_ctx->dcache) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No dcache present"); -                op_ret = 0; -                goto out; -        } - -        /* If we're updating, we must begin with invalidating any previous -         * entries. -         */ -        libgf_dcache_invalidate (fd); - -        fd_ctx->dcache->next = entries->next; -        /* We still need to store a pointer to the head -         * so we start free'ing from the head when invalidation -         * is required. -         * -         * Need to delink the entries from the list -         * given to us by an underlying translators. Most translators will -         * free this list after this call so we must preserve the dirents in -         * order to cache them. -         */ -        list_splice_init (&entries->list, &fd_ctx->dcache->entries.list); -        op_ret = 0; -out: -        return op_ret; -} - -int -libgf_dcache_readdir (libglusterfs_client_ctx_t *ctx, fd_t *fd, -                      struct dirent *dirp, off_t *offset) -{ -        libglusterfs_client_fd_ctx_t    *fd_ctx = NULL; -        int                             cachevalid = 0; - -        if ((!ctx) || (!fd) || (!dirp) || (!offset)) -                return 0; - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                goto out; -        } - -        if (!fd_ctx->dcache) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No dcache present"); -                goto out; -        } - -        /* We've either run out of entries in the cache -         * or the cache is empty. -         */ -        if (!fd_ctx->dcache->next) { -                gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "No entries present"); -                goto out; -        } - -        /* The dirent list is created as a circular linked list -         * so this check is needed to ensure, we dont start -         * reading old entries again. -         * If we're reached this situation, the cache is exhausted -         * and we'll need to pre-fetch more entries to continue serving. -         */ -        if (fd_ctx->dcache->next == &fd_ctx->dcache->entries) { -                gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Entries exhausted"); -                goto out; -        } - -        /* During sequential reading we generally expect that the offset -         * requested is the same as the offset we served in the previous call -         * to readdir. But, seekdir, rewinddir and libgf_dcache_invalidate -         * require special handling because seekdir/rewinddir change the offset -         * in the fd_ctx and libgf_dcache_invalidate changes the prev_off. -         */ -        if (*offset != fd_ctx->dcache->prev_off) { -                /* For all cases of the if branch above, we know that the -                 * cache is now invalid except for the case below. It handles -                 * the case where the two offset values above are different -                 * but different because the previous readdir block was -                 * exhausted, resulting in a prev_off being set to 0 in -                 * libgf_dcache_invalidate, while the requested offset is non -                 * zero because that is what we returned for the last dirent -                 * of the previous readdir block. -                 */ -                if ((*offset != 0) && (fd_ctx->dcache->prev_off == 0)) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Entries" -                                " exhausted"); -                        cachevalid = 1; -                } else -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Dcache" -                                " invalidated previously"); -        } else -                cachevalid = 1; - -        if (!cachevalid) -                goto out; - -        dirp->d_ino = fd_ctx->dcache->next->d_ino; -        strncpy (dirp->d_name, fd_ctx->dcache->next->d_name, -                 fd_ctx->dcache->next->d_len); - -        *offset = fd_ctx->dcache->next->d_off; -        dirp->d_off = *offset; -        fd_ctx->dcache->prev_off = fd_ctx->dcache->next->d_off; -        fd_ctx->dcache->next = fd_ctx->dcache->next->next; - -out: -        return cachevalid; -} - - -int32_t -libgf_client_release (xlator_t *this, -		      fd_t *fd) -{ -	libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -        fd_ctx = libgf_get_fd_ctx (fd); -        if (IA_ISDIR (fd->inode->ia_type)) { -                libgf_dcache_invalidate (fd); -                FREE (fd_ctx->dcache); -        } - -        libgf_del_fd_ctx (fd); -        if (fd_ctx != NULL) { -                pthread_mutex_destroy (&fd_ctx->lock); -                FREE (fd_ctx); -        } - -	return 0; -} - -libglusterfs_client_inode_ctx_t * -libgf_get_inode_ctx (inode_t *inode) -{ -        uint64_t                                ctxaddr = 0; -        libglusterfs_client_inode_ctx_t         *ictx = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, inode, out); -        if (inode_ctx_get (inode, libgf_inode_to_xlator (inode), &ctxaddr) < 0) -                goto out; - -        ictx = (libglusterfs_client_inode_ctx_t *)(long)ctxaddr; - -out: -        return ictx; -} - -libglusterfs_client_inode_ctx_t * -libgf_del_inode_ctx (inode_t *inode) -{ -        uint64_t                                ctxaddr = 0; -        libglusterfs_client_inode_ctx_t         *ictx = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, inode, out); -        if (inode_ctx_del (inode, libgf_inode_to_xlator (inode), &ctxaddr) < 0) -                goto out; - -        ictx = (libglusterfs_client_inode_ctx_t *)(long)ctxaddr; - -out: -        return ictx; -} - -libglusterfs_client_inode_ctx_t * -libgf_alloc_inode_ctx (libglusterfs_client_ctx_t *ctx, inode_t *inode) -{ -        uint64_t                                ctxaddr = 0; -        libglusterfs_client_inode_ctx_t         *ictx = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, inode, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        ictx = CALLOC (1, sizeof (*ictx)); -        if (ictx == NULL) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, -                                "memory allocation failure"); -                goto out; -        } - -        pthread_mutex_init (&ictx->lock, NULL); -        ctxaddr = (uint64_t) (long)ictx; -        if (inode_ctx_put (inode, libgf_inode_to_xlator (inode), ctxaddr) < 0){ -                FREE (ictx); -                ictx = NULL; -        } - -out: -        return ictx; -} - -int -libgf_transform_iattr (libglusterfs_client_ctx_t *libctx, inode_t *inode, -                       struct iatt *buf) -{ - -        if ((!libctx) || (!buf) || (!inode)) -                return -1; - -        buf->ia_dev = libctx->fake_fsid; -        /* If the inode is root, the inode number must be 1 not the -         * ino received from the file system. -         */ -        if ((inode->ino == 1) && (buf)) -                buf->ia_ino = 1; - -        return 0; -} - -int -libgf_update_iattr_cache (inode_t *inode, int flags, struct iatt *buf) -{ -        libglusterfs_client_inode_ctx_t *inode_ctx = NULL; -        time_t                          current = 0; -        int                             op_ret = -1; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, inode, out); - -        inode_ctx = libgf_get_inode_ctx (inode); -        if (!inode_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No inode context" -                        " present"); -                errno = EINVAL; -                op_ret = -1; -                goto out; -        } - -        pthread_mutex_lock (&inode_ctx->lock); -        { -                /* Take a timestamp only after we've acquired the -                 * lock. -                 */ -                current = time (NULL); -                if (flags & LIBGF_UPDATE_LOOKUP) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Updating lookup"); -                        inode_ctx->previous_lookup_time = current; -                } - -                if (flags & LIBGF_UPDATE_STAT) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Updating stat"); - -                        /* Update the cached stat struct only if a new -                         * stat buf is given. -                         */ -                        if (buf != NULL) { -                                inode_ctx->previous_stat_time = current; -                                memcpy (&inode_ctx->stbuf, buf, -                                                sizeof (inode_ctx->stbuf)); -                        } -                } -        } -        pthread_mutex_unlock (&inode_ctx->lock); -        op_ret = 0; - -out: -        return op_ret; -} - - -int -libgf_invalidate_iattr_cache (inode_t *inode, int flags) -{ -        libglusterfs_client_inode_ctx_t         *ictx = NULL; - -        if (!inode) -                return -1; - -        ictx = libgf_get_inode_ctx (inode); -        if (!ictx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No inode context" -                        " present"); -                return -1; -        } - -        pthread_mutex_lock (&ictx->lock); -        { -                if (flags & LIBGF_INVALIDATE_LOOKUP) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Invalidating" -                                " lookup"); -                        ictx->previous_lookup_time = 0; -                } - -                if (flags & LIBGF_INVALIDATE_STAT) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Invalidating" -                                " stat"); -                        ictx->previous_stat_time = 0; -                } - -        } -        pthread_mutex_unlock (&ictx->lock); - -        return 0; -} - - -int -libgf_is_iattr_cache_valid (libglusterfs_client_ctx_t *ctx, inode_t *inode, -                            struct iatt *sbuf, int flags) -{ -        time_t                                  current = 0; -        time_t                                  prev = 0; -        libglusterfs_client_inode_ctx_t         *inode_ctx = NULL; -        int                                     cache_valid = 0; -        time_t                                  timeout = 0; - -        if (inode == NULL) -                return 0; - -        inode_ctx = libgf_get_inode_ctx (inode); -        if (!inode_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No inode context" -                        " present\n"); -                return 0; -        } - -        pthread_mutex_lock (&inode_ctx->lock); -        { -                current = time (NULL); -                if (flags & LIBGF_VALIDATE_LOOKUP) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Checking lookup"); -                        prev = inode_ctx->previous_lookup_time; -                        timeout = ctx->lookup_timeout; -                } else { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Checking stat"); -                        prev = inode_ctx->previous_stat_time; -                        timeout = ctx->stat_timeout; -                } - -                /* Even if the timeout is set to -1 to cache -                 * infinitely, fops like write must invalidate the -                 * stat cache because writev_cbk cannot update -                 * the cache using the stat returned to it. This is -                 * because write-behind can return a stat bufs filled -                 * with zeroes. -                 */ -                if (prev == 0) { -                        cache_valid = 0; -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Cache Invalid"); -                        goto iattr_unlock_out; -                } - -                /* Cache infinitely */ -                if (timeout == (time_t)-1) { -                        cache_valid = 1; -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Caching On and " -                                "valid"); -                        goto iattr_unlock_out; -                } - -                /* Disable caching completely */ -                if (timeout == 0) { -                        cache_valid = 0; -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Cache disabled"); -                        goto iattr_unlock_out; -                } - -                if ((prev > 0) && (timeout >= (current - prev))) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Cache valid"); -                        cache_valid = 1; -                } - -                if (flags & LIBGF_VALIDATE_LOOKUP) -                        goto iattr_unlock_out; - -                if ((cache_valid) && (sbuf)) -                        *sbuf = inode_ctx->stbuf; -        } -iattr_unlock_out: -        pthread_mutex_unlock (&inode_ctx->lock); - -        return cache_valid; -} - -int32_t -libgf_client_releasedir (xlator_t *this, -			 fd_t *fd) -{ -	libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -        fd_ctx = libgf_get_fd_ctx (fd); -        if (IA_ISDIR (fd->inode->ia_type)) { -                libgf_dcache_invalidate (fd); -                FREE (fd_ctx->dcache); -        } - -        libgf_del_fd_ctx (fd); -        if (fd_ctx != NULL) { -                pthread_mutex_destroy (&fd_ctx->lock); -                FREE (fd_ctx); -        } - -	return 0; -} - -void *poll_proc (void *ptr) -{ -        glusterfs_ctx_t *ctx = ptr; - -        event_dispatch (ctx->event_pool); - -        return NULL; -} - - -int32_t -xlator_graph_init (xlator_t *xl) -{ -        xlator_t *trav = xl; -        int32_t ret = -1; - -        while (trav->prev) -                trav = trav->prev; - -        while (trav) { -                if (!trav->ready) { -                        ret = xlator_tree_init (trav); -                        if (ret < 0) -                                break; -                } -                trav = trav->next; -        } - -        return ret; -} - - -void -xlator_graph_fini (xlator_t *xl) -{ -	xlator_t *trav = xl; -	while (trav->prev) -		trav = trav->prev; - -	while (trav) { -		if (!trav->init_succeeded) { -			break; -		} - -		xlator_tree_fini (trav); -		trav = trav->next; -	} -} - -/* Returns a pointer to the @n'th char matching - * @c in string @str, starting the search from right or - * end-of-string, rather than starting from left, as rindex - * function does. - */ -char * -libgf_rrindex (char *str, int c, int n) -{ -        size_t  len; -        int     occurrence = 0; - -        if (str == NULL) -                return NULL; - -        len = strlen (str); -        /* Point to last character of string. */ -        if (len) -                str += (len - 1); -        while (len > 0) { -                if ((int)*str == c) { -                        ++occurrence; -                        if (occurrence == n) -                                break; -                } -                --len; -                --str; -        } - -        return str; -} - -char * -libgf_trim_to_prev_dir (char * path) -{ -        char    *idx = NULL; -        int      len = 0; - -        if (!path) -                return NULL; - -        /* Check if we're already at root, if yes -         * then there is no prev dir. -         */ -        len = strlen (path); -        if (len <= 1) -                return path; - -        if (path[len - 1] == '/') { -                path[len - 1] = '\0'; -        } - -        idx = libgf_rrindex (path, '/', 1); -        /* Move to the char after the / */ -        ++idx; -        *idx = '\0'; - -        return path; -} - - -char * -libgf_prepend_cwd (const char *userpath, char *abspath, int size) -{ -        if ((!userpath) || (!abspath)) -                return NULL; - -        if (!getcwd (abspath, size)) -                return NULL; - -        strcat (abspath, "/"); -        strcat (abspath, userpath); - -        return abspath; -} - - -/* Performs a lightweight path resolution that only - * looks for . and  .. and replaces those with the - * proper names. - * - * FIXME: This is a stop-gap measure till we have full - * fledge path resolution going in here. - * Function returns path strdup'ed so remember to FREE the - * string as required. - */ -char * -libgf_resolve_path_light (char *path) -{ -        char            *respath = NULL; -        char            *saveptr = NULL; -        char            *tok = NULL; -        int             len = 0; -        int             addslash = 0; -        char            mypath[PATH_MAX]; - -        if (!path) -                goto out; - -        memset (mypath, 0, PATH_MAX); - -        if (!libgf_path_absolute (path)) -                libgf_prepend_cwd (path, mypath, PATH_MAX); -        else -                strcpy (mypath, path); - -        len = strlen (mypath); -        if (len == 0) { -                goto out; -        } - -        respath = calloc (PATH_MAX, sizeof (char)); -        if (respath == NULL) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR,"Memory allocation failed"); -                goto out; -        } - -        /* The path only contains a / or a //, so simply add a / -         * and return. -         * This needs special handling because the loop below does -         * not allow us to do so through strtok. -         */ -        if (((mypath[0] == '/') && (len == 1)) -                        || (strcmp (mypath, "//") == 0)) { -                strcat (respath, "/"); -                goto out; -        } - -        tok = strtok_r (mypath, "/", &saveptr); -        addslash = 0; -        strcat (respath, "/"); -        while (tok) { -                if (addslash) { -                        if ((strcmp (tok, ".") != 0) -                                        && (strcmp (tok, "..") != 0)) { -                                strcat (respath, "/"); -                        } -                } - -                if ((strcmp (tok, ".") != 0) && (strcmp (tok, "..") != 0)) { -                        strcat (respath, tok); -                        addslash = 1; -                } else if ((strcmp (tok, "..") == 0)) { -                        libgf_trim_to_prev_dir (respath); -                        addslash = 0; -                } - -                tok = strtok_r (NULL, "/", &saveptr); -        } - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Path: %s, Resolved Path: %s", -                path, respath); -out: -        return respath; -} - -void  -libgf_client_loc_wipe (loc_t *loc) -{ -	if (loc->path) { -		FREE (loc->path); -	} - -	if (loc->parent) {  -		inode_unref (loc->parent); -		loc->parent = NULL; -	} - -	if (loc->inode) { -		inode_unref (loc->inode); -		loc->inode = NULL; -	} - -	loc->path = loc->name = NULL; -        loc->ino = 0; -} - - -int32_t -libgf_client_loc_fill (loc_t *loc, -		       libglusterfs_client_ctx_t *ctx, -		       ino_t ino, -		       ino_t par, -		       const char *name) -{ -        inode_t *inode = NULL, *parent = NULL; -	int32_t ret = -1; -	char *path = NULL; - -        /* resistance against multiple invocation of loc_fill not to get -           reference leaks via inode_search() */ - -        inode = loc->inode; -	 -        if (!inode) { -                if (ino) -                        inode = inode_search (ctx->itable, ino, NULL); - -                if (inode) -                        goto inode_found; - -                if (par && name) -                        inode = inode_search (ctx->itable, par, name); -        } - -inode_found: -        if (inode) { -                loc->ino = inode->ino; -                loc->inode = inode; -        } - -        parent = loc->parent; -        if (!parent) { -                if (inode) -                        parent = inode_parent (inode, par, name); -                else -                        parent = inode_search (ctx->itable, par, NULL); -                loc->parent = parent; -        } -   -	if (!loc->path) { -		if (name && parent) { -			ret = inode_path (parent, name, &path); -			if (ret <= 0) { -				gf_log ("glusterfs-fuse", GF_LOG_ERROR, -					"inode_path failed for %"PRId64"/%s", -					parent->ino, name); -				goto fail; -			} else { -				loc->path = path; -			} -		} else 	if (inode) { -			ret = inode_path (inode, NULL, &path); -			if (ret <= 0) { -				gf_log ("glusterfs-fuse", GF_LOG_ERROR, -					"inode_path failed for %"PRId64, -					inode->ino); -				goto fail; -			} else { -				loc->path = path; -			} -		} -	} - -	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_ERROR, -			"failed to search parent for %"PRId64"/%s (%"PRId64")", -			(ino_t)par, name, (ino_t)ino); -		ret = -1; -		goto fail; -	} -	ret = 0; -fail: -	return ret; -} - - -static call_frame_t * -get_call_frame_for_req (libglusterfs_client_ctx_t *ctx, char d) -{ -        call_pool_t  *pool = ctx->gf_ctx.pool; -        xlator_t     *this = ctx->gf_ctx.graph; -        call_frame_t *frame = NULL; -   - -        frame = create_frame (this, pool); - -        frame->root->uid = geteuid (); -        frame->root->gid = getegid (); -        frame->root->pid = ctx->pid; -        frame->root->unique = ctx->counter++; -   -        return frame; -} - -void  -libgf_client_fini (xlator_t *this) -{ -	FREE (this->private); -        return; -} - - -int32_t -libgf_client_notify (xlator_t *this,  -                     int32_t event, -                     void *data,  -                     ...) -{ -        libglusterfs_client_private_t *priv = this->private; - -        switch (event) -        { -        case GF_EVENT_CHILD_UP: -                pthread_mutex_lock (&priv->lock); -                { -                        priv->complete = 1; -                        pthread_cond_broadcast (&priv->init_con_established); -                } -                pthread_mutex_unlock (&priv->lock); -                break; - -        default: -                default_notify (this, event, data); -        } - -        return 0; -} - -int32_t  -libgf_client_init (xlator_t *this) -{ -        return 0; -} - -glusterfs_handle_t  -glusterfs_init (glusterfs_init_params_t *init_ctx, uint32_t fakefsid) -{ -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_private_t *priv = NULL; -        FILE *specfp = NULL; -        xlator_t *graph = NULL, *trav = NULL; -        call_pool_t *pool = NULL; -        int32_t ret = 0; -        struct rlimit lim; -	uint32_t xl_count = 0; -        loc_t       new_loc = {0, }; -        struct timeval tv = {0, }; -        uint32_t       len = 0; -        char           buf[PATH_MAX]; - -        if (!init_ctx || (!init_ctx->specfile && !init_ctx->specfp)) { -                errno = EINVAL; -                return NULL; -        } - -        ctx = CALLOC (1, sizeof (*ctx)); -        if (!ctx) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: out of memory\n", -			 __FILE__, __PRETTY_FUNCTION__, __LINE__); - -                errno = ENOMEM; -                return NULL; -        } - -        ctx->lookup_timeout = init_ctx->lookup_timeout; -        ctx->stat_timeout = init_ctx->stat_timeout; -        ctx->fake_fsid = fakefsid; -        ctx->pid = getpid (); -        pthread_mutex_init (&ctx->gf_ctx.lock, NULL); -   -        pool = ctx->gf_ctx.pool = CALLOC (1, sizeof (call_pool_t)); -        if (!pool) { -                errno = ENOMEM; -                FREE (ctx); -                return NULL; -        } - -        LOCK_INIT (&pool->lock); -        INIT_LIST_HEAD (&pool->all_frames); - -	/* FIXME: why is count hardcoded to 16384 */ -        ctx->gf_ctx.event_pool = event_pool_new (16384); -        ctx->gf_ctx.page_size  = LIBGF_IOBUF_SIZE; -        ctx->gf_ctx.iobuf_pool = iobuf_pool_new (8 * 1048576, -                                                 ctx->gf_ctx.page_size); - -        lim.rlim_cur = RLIM_INFINITY; -        lim.rlim_max = RLIM_INFINITY; -        setrlimit (RLIMIT_CORE, &lim); -        setrlimit (RLIMIT_NOFILE, &lim); - -        ctx->gf_ctx.cmd_args.log_level = GF_LOG_WARNING; - -        if (init_ctx->logfile) -                ctx->gf_ctx.cmd_args.log_file = strdup (init_ctx->logfile); -        else -                ctx->gf_ctx.cmd_args.log_file = strdup ("/dev/stderr"); - -        if (init_ctx->loglevel) { -                if (!strncasecmp (init_ctx->loglevel, "DEBUG", -                                  strlen ("DEBUG"))) { -                        ctx->gf_ctx.cmd_args.log_level = GF_LOG_DEBUG; -                } else if (!strncasecmp (init_ctx->loglevel, "WARNING", -                                         strlen ("WARNING"))) { -                        ctx->gf_ctx.cmd_args.log_level = GF_LOG_WARNING; -                } else if (!strncasecmp (init_ctx->loglevel, "CRITICAL", -                                         strlen ("CRITICAL"))) { -                        ctx->gf_ctx.cmd_args.log_level = GF_LOG_CRITICAL; -                } else if (!strncasecmp (init_ctx->loglevel, "NONE", -                                         strlen ("NONE"))) { -                        ctx->gf_ctx.cmd_args.log_level = GF_LOG_NONE; -                } else if (!strncasecmp (init_ctx->loglevel, "ERROR", -                                         strlen ("ERROR"))) { -                        ctx->gf_ctx.cmd_args.log_level = GF_LOG_ERROR; -                } else if (!strncasecmp (init_ctx->loglevel, "TRACE", -                                         strlen ("TRACE"))) { -                        ctx->gf_ctx.cmd_args.log_level = GF_LOG_TRACE; -                } else { -			fprintf (stderr,  -				 "libglusterfsclient: %s:%s():%d: Unrecognized log-level \"%s\", possible values are \"DEBUG|WARNING|[ERROR]|CRITICAL|NONE|TRACE\"\n", -                                 __FILE__, __PRETTY_FUNCTION__, __LINE__, -                                 init_ctx->loglevel); -			FREE (ctx->gf_ctx.cmd_args.log_file); -                        FREE (ctx->gf_ctx.pool); -                        FREE (ctx->gf_ctx.event_pool); -                        FREE (ctx); -                        errno = EINVAL; -                        return NULL; -                } -        } - -	if (first_init) -        { -                memset (buf, 0, PATH_MAX); - -                if (getcwd (buf, PATH_MAX) == NULL) { -                        fprintf (stderr, "libglusterfsclient: cannot get " -                                 "current working directory (%s)", -                                 strerror (errno)); -			FREE (ctx->gf_ctx.cmd_args.log_file); -                        FREE (ctx->gf_ctx.pool); -                        FREE (ctx->gf_ctx.event_pool); -                        FREE (ctx); -                        return NULL; -                } - -                len = strlen (buf); -                if ((buf[len - 1] != '/')) { -                        if ((len + 2) > PATH_MAX) { -                                errno = ENAMETOOLONG; -                                fprintf (stderr, "libglusterfsclient: cannot" -                                         "get current working directory (%s)", -                                         strerror (errno)); -                                FREE (ctx->gf_ctx.cmd_args.log_file); -                                FREE (ctx->gf_ctx.pool); -                                FREE (ctx->gf_ctx.event_pool); -                                FREE (ctx); -                                return NULL; -                        } - -                        strcat (buf, "/"); -                } - -                pthread_mutex_lock (&cwdlock); -                { -                        strcpy (cwd, buf); -                        cwd_inited = 1; -                } -                pthread_mutex_unlock (&cwdlock); - -                ret = gf_log_init (ctx->gf_ctx.cmd_args.log_file); -                if (ret == -1) { -			fprintf (stderr,  -				 "libglusterfsclient: %s:%s():%d: failed to open logfile \"%s\"\n",  -				 __FILE__, __PRETTY_FUNCTION__, __LINE__,  -				 ctx->gf_ctx.cmd_args.log_file); -			FREE (ctx->gf_ctx.cmd_args.log_file); -                        FREE (ctx->gf_ctx.pool); -                        FREE (ctx->gf_ctx.event_pool); -                        FREE (ctx); -                        return NULL; -                } - -                gf_log_set_loglevel (ctx->gf_ctx.cmd_args.log_level); -        } - -        if (init_ctx->specfp) { -                specfp = init_ctx->specfp; -                if (fseek (specfp, 0L, SEEK_SET)) { -			fprintf (stderr,  -				 "libglusterfsclient: %s:%s():%d: fseek on volume file stream failed (%s)\n", -                                 __FILE__, __PRETTY_FUNCTION__, __LINE__, -                                 strerror (errno)); -			FREE (ctx->gf_ctx.cmd_args.log_file); -                        FREE (ctx->gf_ctx.pool); -                        FREE (ctx->gf_ctx.event_pool); -                        FREE (ctx); -                        return NULL; -                } -        } else if (init_ctx->specfile) {  -                specfp = fopen (init_ctx->specfile, "r"); -                ctx->gf_ctx.cmd_args.volume_file = strdup (init_ctx->specfile); -        } - -        if (!specfp) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: could not open volfile: %s\n",  -			 __FILE__, __PRETTY_FUNCTION__, __LINE__, -                         strerror (errno)); -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -                FREE (ctx); -                return NULL; -        } - -        if (init_ctx->volume_name) { -                ctx->gf_ctx.cmd_args.volume_name = strdup (init_ctx->volume_name); -        } - -	graph = file_to_xlator_tree (&ctx->gf_ctx, specfp); -        if (!graph) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: cannot create configuration graph (%s)\n", -			 __FILE__, __PRETTY_FUNCTION__, __LINE__, -                         strerror (errno)); - -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.cmd_args.volume_name); -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -                FREE (ctx); -                return NULL; -        } - -        if (init_ctx->volume_name) { -                trav = graph; -                while (trav) { -                        if (strcmp (trav->name, init_ctx->volume_name) == 0) { -                                graph = trav; -                                break; -                        } -                        trav = trav->next; -                } -        } - -        ctx->gf_ctx.graph = libglusterfs_graph (graph); -        if (!ctx->gf_ctx.graph) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: graph creation failed (%s)\n", -			 __FILE__, __PRETTY_FUNCTION__, __LINE__, -                         strerror (errno)); - -		xlator_tree_free (graph); -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.cmd_args.volume_name); -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -                FREE (ctx); -                return NULL; -        } -        graph = ctx->gf_ctx.graph; -        ctx->gf_ctx.top = graph; - -	trav = graph; -	while (trav) { -		xl_count++;  /* Getting this value right is very important */ -		trav = trav->next; -	} - -	ctx->gf_ctx.xl_count = xl_count + 1; - -        priv = CALLOC (1, sizeof (*priv)); -        if (!priv) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: cannot allocate memory (%s)\n", -			 __FILE__, __PRETTY_FUNCTION__, __LINE__, -                         strerror (errno)); - -		xlator_tree_free (graph); -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.cmd_args.volume_name); -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -                /* inode_table_destroy (ctx->itable); */ -                FREE (ctx); -          -                return NULL; -        } - -        pthread_cond_init (&priv->init_con_established, NULL); -        pthread_mutex_init (&priv->lock, NULL); - -        graph->private = priv; -        ctx->itable = inode_table_new (LIBGLUSTERFS_INODE_TABLE_LRU_LIMIT, -                                       graph); -        if (!ctx->itable) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: cannot create inode table\n", -			 __FILE__, __PRETTY_FUNCTION__, __LINE__); -		xlator_tree_free (graph);  -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.cmd_args.volume_name); - -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -		xlator_tree_free (graph);  -                /* TODO: destroy graph */ -                /* inode_table_destroy (ctx->itable); */ -                FREE (ctx); -          -                return NULL; -        } - -	set_global_ctx_ptr (&ctx->gf_ctx); -	ctx->gf_ctx.process_uuid = zr_build_process_uuid (); - -        if (xlator_graph_init (graph) == -1) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: graph initialization failed\n", -			 __FILE__, __PRETTY_FUNCTION__, __LINE__); -		xlator_tree_free (graph); -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.cmd_args.volume_name); -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -                /* TODO: destroy graph */ -                /* inode_table_destroy (ctx->itable); */ -                FREE (ctx); -                return NULL; -        } - -	/* Send notify to all translator saying things are ready */ -	graph->notify (graph, GF_EVENT_PARENT_UP, graph); - -        if (gf_timer_registry_init (&ctx->gf_ctx) == NULL) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: timer init failed (%s)\n",  -			 __FILE__, __PRETTY_FUNCTION__, __LINE__, -                         strerror (errno)); - -		xlator_graph_fini (graph); -		xlator_tree_free (graph); -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.cmd_args.volume_name); - -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -                /* TODO: destroy graph */ -                /* inode_table_destroy (ctx->itable); */ -                FREE (ctx); -                return NULL; -        } - -        if ((ret = pthread_create (&ctx->reply_thread, NULL, poll_proc, -                                   (void *)&ctx->gf_ctx))) { -		fprintf (stderr,  -			 "libglusterfsclient: %s:%s():%d: reply thread creation failed\n",  -			 __FILE__, __PRETTY_FUNCTION__, __LINE__); -		xlator_graph_fini (graph); -		xlator_tree_free (graph); -		FREE (ctx->gf_ctx.cmd_args.log_file); -                FREE (ctx->gf_ctx.cmd_args.volume_file); -                FREE (ctx->gf_ctx.cmd_args.volume_name); - -                FREE (ctx->gf_ctx.pool); -                FREE (ctx->gf_ctx.event_pool); -                /* TODO: destroy graph */ -                /* inode_table_destroy (ctx->itable); */ -                FREE (ctx); -                return NULL; -        } - -        pthread_mutex_lock (&priv->lock);  -        { -                while (!priv->complete) { -                        pthread_cond_wait (&priv->init_con_established, -                                           &priv->lock); -                } -        } -        pthread_mutex_unlock (&priv->lock); - -        /*  -         * wait for some time to allow initialization of all children of  -         * distribute before sending lookup on '/' -         */ - -        tv.tv_sec = 0; -        tv.tv_usec = (100 * 1000); -        select (0, NULL, NULL, NULL, &tv); - -        /* workaround for xlators like dht which require lookup to be sent -         * on / */ -        libgf_client_loc_fill (&new_loc, ctx, 1, 0, "/"); -        ret = libgf_client_lookup (ctx, &new_loc, NULL, NULL, NULL); -        if (ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, "lookup of /" -                        " failed"); -                return NULL; -        } -        libgf_client_loc_wipe (&new_loc); - -	first_init = 0; -  -        return ctx; -} - -struct vmp_entry * -libgf_init_vmpentry (char *vmp, glusterfs_handle_t *vmphandle) -{ -        struct vmp_entry        *entry = NULL; -        size_t                  vmplen = 0; -        int                     appendslash = 0; -        int                     ret = -1; - -        entry = CALLOC (1, sizeof (struct vmp_entry)); -        if (!entry) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR,"Memory allocation failed"); -                return NULL; -        } - -        vmplen = strlen (vmp); -        assert (vmplen > 0); -        if (vmp[vmplen - 1] != '/') { -                vmplen++; -                appendslash = 1; -        } - -        entry->vmp = CALLOC (vmplen + 1, sizeof (char)); -        if (!entry->vmp) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Memory allocation " -                        "failed"); -                goto free_entry; -        } - -        strcpy (entry->vmp, vmp); -        if (appendslash) { -                entry->vmp[vmplen-1] = '/'; -                entry->vmp[vmplen] = '\0'; -        } -  -        entry->vmplen = vmplen; -        entry->handle = vmphandle; -        INIT_LIST_HEAD (&entry->list); -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "New VMP entry: %s", vmp); - -        ret = 0; - -free_entry: -        if (ret == -1) { -                if (entry->vmp) -                        FREE (entry->vmp); -                if (entry) -                        FREE (entry); -                entry = NULL; -        } -        return entry; -} - -void -libgf_free_vmp_entry (struct vmp_entry *entry) -{ -        FREE (entry->vmp); -        FREE (entry); -} - -int -libgf_count_path_components (char *path) -{ -        int     compos = 0; -        char    *pathdup = NULL; -        int     len = 0; - -        if (!path || !*path) -                return -1; - -        pathdup = strdup (path); -        if (!pathdup) -                return -1; - -        len = strlen (pathdup); -        if (pathdup[len - 1] == '/') -                pathdup[len - 1] = '\0'; - -        path = pathdup; -        while ((path = strchr (path, '/'))) { -                compos++; -                ++path; -        } - -        free (pathdup); -        return compos; -} - -/* Returns the number of components that match between - * the VMP and the path. Assumes string1 is vmp entry. - * Assumes both are absolute paths. - */ -int -libgf_strmatchcount (char *string1, char *string2) -{ -        int     matchcount = 0; -        char    *s1dup = NULL, *s2dup = NULL; -        char    *tok1 = NULL, *saveptr1 = NULL; -        char    *tok2 = NULL, *saveptr2 = NULL; - -        if ((!string1) || (!string2)) -                return 0; - -        s1dup = strdup (string1); -        if (!s1dup) -                return 0; - -        s2dup  = strdup (string2); -        if (!s2dup) -                goto free_s1; - -        string1 = s1dup; -        string2 = s2dup; - -        tok1 = strtok_r(string1, "/", &saveptr1); -        tok2 = strtok_r (string2, "/", &saveptr2); -        while (tok1) { -                if (!tok2) -                        break; - -                if (strcmp (tok1, tok2) != 0) -                        break; - -                matchcount++; -                tok1 = strtok_r(NULL, "/", &saveptr1); -                tok2 = strtok_r (NULL, "/", &saveptr2); -        } - -        free (s2dup); -free_s1: -        free (s1dup); -        return matchcount; -} - -int -libgf_vmp_entry_match (struct vmp_entry *entry, char *path) -{ -        return libgf_strmatchcount (entry->vmp, path); -} - -#define LIBGF_VMP_EXACT          1 -#define LIBGF_VMP_LONGESTPREFIX  0 - - -/* copies vmp from the vmp-entry having glusterfs handle @handle, into @vmp */ -char * -libgf_vmp_search_vmp (glusterfs_handle_t handle, char *vmp, size_t vmp_size) -{ -        char             *res   = NULL; -        struct vmp_entry *entry = NULL; - -        if (handle == NULL) { -                goto out; -        } - -        pthread_mutex_lock (&vmplock); -        { -                if (vmplist.entries == 0) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Virtual Mount Point " -                                "list is empty."); -                        goto unlock; -                } - -                list_for_each_entry(entry, &vmplist.list, list) { -                        if (entry->handle == handle) { -                                if ((vmp_size) < (strlen (entry->vmp) + 1)) { -                                        errno = ENAMETOOLONG; -                                        goto unlock; -                                } - -                                strcpy (vmp, entry->vmp); -                                res = vmp; -                                break; -                        } -                } -        } -unlock: -        pthread_mutex_unlock (&vmplock); - -out: -        return res; -} - - -struct vmp_entry * -_libgf_vmp_search_entry (char *path, int searchtype) -{ -        struct vmp_entry        *entry = NULL; -        int                     matchcount = 0; -        struct vmp_entry        *maxentry = NULL; -        int                     maxcount = 0; -        int                     vmpcompcount = 0; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "VMP Search: path %s, type: %s", -                path, (searchtype == LIBGF_VMP_EXACT)?"Exact":"LongestPrefix"); -        if (vmplist.entries == 0) { -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Virtual Mount Point " -                        "list is empty."); -                goto out; -        } - -        list_for_each_entry(entry, &vmplist.list, list) { -                vmpcompcount = libgf_count_path_components (entry->vmp); -                matchcount = libgf_vmp_entry_match (entry, path); -                gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Candidate VMP:  %s," -                        " Matchcount: %d", entry->vmp, matchcount); -                if ((matchcount > maxcount) && (matchcount == vmpcompcount)) { -                        maxcount = matchcount; -                        maxentry = entry; -                } -        } - -        /* To ensure that the longest prefix matched entry is also an exact -         * match, this is used to check whether duplicate entries are present -         * in the vmplist. -         */ -        vmpcompcount = 0; -        if ((searchtype == LIBGF_VMP_EXACT) && (maxentry)) { -                vmpcompcount = libgf_count_path_components (maxentry->vmp); -                matchcount = libgf_count_path_components (path); -                gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Exact Check: VMP: %s," -                        " CompCount: %d, Path: %s, CompCount: %d", -                        maxentry->vmp, vmpcompcount, path, matchcount); -                if (vmpcompcount != matchcount) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "No Match"); -                        maxentry = NULL; -                } else -                        gf_log (LIBGF_XL_NAME, GF_LOG_TRACE, "Matches!"); -        } - -out:         -        return maxentry; -}  - -/* Used to search for a exactly matching VMP entry. - */ -struct vmp_entry * -libgf_vmp_search_exact_entry (char *path) -{ -        struct vmp_entry        *entry = NULL; - -        if (!path) -                goto out; - -        pthread_mutex_lock (&vmplock); -        { -                entry = _libgf_vmp_search_entry (path, LIBGF_VMP_EXACT); -        } -        pthread_mutex_unlock (&vmplock); - -out: -        if (entry) -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "VMP Entry found: path :%s" -                        " vmp: %s", path, entry->vmp); -        else -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "VMP Entry not found: path" -                        ": %s", path); - -        return entry; -} - - -/* Used to search for a longest prefix matching VMP entry. - */ -struct vmp_entry * -libgf_vmp_search_entry (char *path) -{ -        struct vmp_entry        *entry = NULL; - -        if (!path) -                goto out; - -        pthread_mutex_lock (&vmplock); -        { -                entry = _libgf_vmp_search_entry (path, LIBGF_VMP_LONGESTPREFIX); -        } -        pthread_mutex_unlock (&vmplock); - -out: -        if (entry) -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "VMP Entry found: path :%s" -                        " vmp: %s", path, entry->vmp); -        else -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "VMP Entry not found: path" -                        ": %s", path); - -        return entry; -} - -int -libgf_vmp_map_ghandle (char *vmp, glusterfs_handle_t *vmphandle) -{ -        int                     ret = -1; -        struct vmp_entry        *vmpentry = NULL; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "New Entry: %s", vmp); -        vmpentry = libgf_init_vmpentry (vmp, vmphandle); -        if (!vmpentry) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Failed to create VMP" -                        " entry"); -                goto out; -        } - -        pthread_mutex_lock (&vmplock); -        { -                if (vmplist.entries == 0) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Empty list"); -                        INIT_LIST_HEAD (&vmplist.list); -                } - -                list_add_tail (&vmpentry->list, &vmplist.list); -                ++vmplist.entries; -        } -        pthread_mutex_unlock (&vmplock); -        ret = 0; - -out: -        return ret; -} - -/* Path must be validated already. */ -glusterfs_handle_t -libgf_vmp_get_ghandle (char * path) -{ -        struct vmp_entry        *entry = NULL; - -        entry = libgf_vmp_search_entry (path); - -        if (entry == NULL) -                return NULL; - -        return entry->handle; -} - - -/* Returns the handle for the path given in @path, - * @path can be a relative path. The point is, here we - * perform any path resolution that is needed and then - * search for the corresponding vmp handle. - * @vpath is a result-value argument in that the virtual - * path inside the handle is copied into it. - */ -glusterfs_handle_t -libgf_resolved_path_handle (const char *path, char *vpath) -{ -        char                    *respath = NULL; -        struct vmp_entry        *entry = NULL; -        glusterfs_handle_t      handle = NULL; -        char                    *tmp = NULL; - -        if ((!path) || (!vpath)) -                return NULL; - -        /* We only want compaction before VMP entry search because the -         * VMP cannot be search unless we have an absolute path. -         * For absolute paths, we search for VMP first, then perform the -         * path compaction on the  given virtual path. -         */ -        if (!libgf_path_absolute (path)) { -                respath = libgf_resolve_path_light ((char *)path); -                if (respath == NULL) -                        return NULL; -        } - -        /* This condition is needed because in case of absolute paths, the path -         * would already include the VMP and we want to ensure that any path -         * compaction that happens does not exclude the VMP. In the absence of -         * this condition an absolute path might get compacted to "/", i.e. -         * exclude the VMP, and the search will fail. -         * -         * For relative paths, respath will aleady include a potential VMP -         * as a consequence of us prepending the CWD in resolve_light above. -         */ -        if (libgf_path_absolute (path)) { -                entry = libgf_vmp_search_entry ((char *)path); -                if (!entry) -                        goto free_respath; -                tmp = libgf_vmp_virtual_path (entry, path, vpath); -                if (!tmp) -                        goto free_respath; - -                respath = libgf_resolve_path_light (vpath); -                strcpy (vpath, respath); -        } else { -                entry = libgf_vmp_search_entry (respath); -                if (!entry) -                        goto free_respath; -                tmp = libgf_vmp_virtual_path (entry, respath, vpath); -                if (!tmp) -                        goto free_respath; -        } - -        handle = entry->handle; -free_respath: -        if (respath) -                free (respath); /* Alloced in libgf_resolve_path_light */ - -        return handle; -} - - -int -glusterfs_mount (char *vmp, glusterfs_init_params_t *ipars) -{ -        glusterfs_handle_t      vmphandle = NULL; -        int                     ret = -1; -        char                    *vmp_resolved = NULL; -        struct vmp_entry        *vmp_entry = NULL; -        uint32_t                vmphash = 0; -         -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, vmp, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ipars, out); - -        vmp_resolved = libgf_resolve_path_light (vmp); -        if (!vmp_resolved) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Path compaction failed"); -                goto out; -        } - -        vmphash = (dev_t)ReallySimpleHash (vmp, strlen (vmp)); -        pthread_mutex_lock (&mountlock); -        { -                vmp_entry = libgf_vmp_search_exact_entry (vmp); -                if (vmp_entry) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Entry exists"); -                        ret = 0; -                        goto unlock; -                } - -                vmphandle = glusterfs_init (ipars, vmphash); -                if (!vmphandle) { -                        errno = EINVAL; -                        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "GlusterFS context" -                                " init failed"); -                        goto unlock; -                } - -                ret = libgf_vmp_map_ghandle (vmp_resolved, vmphandle); -                if (ret == -1) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Failed to map new" -                                " handle: %s", vmp); -                        glusterfs_fini (vmphandle); -                } -        } -unlock: -        pthread_mutex_unlock (&mountlock); - -out: -        if (vmp_resolved) -                FREE (vmp_resolved); - -        return ret; -} - -inline int -_libgf_umount (char *vmp) -{ -        struct vmp_entry *entry= NULL; -        int               ret = -1; - -        entry = _libgf_vmp_search_entry (vmp, LIBGF_VMP_EXACT); -        if (entry == NULL) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path (%s) not mounted", vmp); -                goto out; -        } - -        if (entry->handle == NULL) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path (%s) has no corresponding glusterfs handle", -                        vmp); -                goto out; -        } - -/*        ret = glusterfs_fini (entry->handle); */ -        list_del_init (&entry->list); -        libgf_free_vmp_entry (entry); - -        vmplist.entries--;  - -out: -        return ret; -} - -inline int -libgf_umount (char *vmp) -{ -        int ret = -1; - -        pthread_mutex_lock (&vmplock); -        {  -                ret = _libgf_umount (vmp); -        } -        pthread_mutex_unlock (&vmplock); -         -        return ret; -} - -int -glusterfs_umount (char *vmp) -{  -        int    ret = -1;  -        char *vmp_resolved = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, vmp, out); - -        vmp_resolved = libgf_resolve_path_light (vmp); -        if (!vmp_resolved) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Path compaction failed"); -                goto out; -        } - -        ret = libgf_umount (vmp_resolved); - -out: -        if (vmp_resolved) -                FREE (vmp_resolved); - -        return ret; -} - -int -glusterfs_umount_all (void) -{ -        struct vmp_entry *entry = NULL, *tmp = NULL; - -        pthread_mutex_lock (&vmplock); -        { -                if (vmplist.entries > 0) { -                        list_for_each_entry_safe (entry, tmp, &vmplist.list, -                                                  list) { -                                /* even if there are errors, continue with other -                                   mounts -                                */ -                                _libgf_umount (entry->vmp); -                        } -                } -        } -        pthread_mutex_unlock (&vmplock); -         -        return 0; -} - -void -glusterfs_reset (void) -{ -        INIT_LIST_HEAD (&vmplist.list); -        vmplist.entries = 0; - -        memset (&vmplock, 0, sizeof (vmplock)); -        pthread_mutex_init (&vmplock, NULL); - -	first_init = 1; -} - -void  -glusterfs_log_lock (void) -{ -	gf_log_lock (); -} - - -void glusterfs_log_unlock (void) -{ -	gf_log_unlock (); -} - - -void -libgf_wait_for_frames_unwind (libglusterfs_client_ctx_t *ctx) -{ -        call_pool_t     *pool = NULL; -        int             canreturn = 0; - -        if (!ctx) -                return; - -        pool = (call_pool_t *)ctx->gf_ctx.pool; -        while (1) { -                LOCK (&pool->lock); -                { -                        if (pool->cnt == 0) { -                                canreturn = 1; -                                goto unlock_out; -                        } -                } -unlock_out: -                UNLOCK (&pool->lock); - -                if (canreturn) -                        break; - -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Waiting for call frames"); -                sleep (1); -        } - -        return; -} - - -int  -glusterfs_fini (glusterfs_handle_t handle) -{ -	libglusterfs_client_ctx_t *ctx = handle; - -        libgf_wait_for_frames_unwind (ctx); - -	FREE (ctx->gf_ctx.cmd_args.log_file); -	FREE (ctx->gf_ctx.cmd_args.volume_file); -	FREE (ctx->gf_ctx.cmd_args.volume_name); -	FREE (ctx->gf_ctx.pool); -        FREE (ctx->gf_ctx.event_pool); -        mem_pool_destroy (ctx->itable->inode_pool); -	 mem_pool_destroy (ctx->itable->dentry_pool); -	 mem_pool_destroy (ctx->itable->fd_mem_pool); -        /* iobuf_pool_destroy (ctx->gf_ctx.iobuf_pool); */ -        ((gf_timer_registry_t *)ctx->gf_ctx.timer)->fin = 1; - -	xlator_graph_fini (ctx->gf_ctx.graph); -	xlator_tree_free (ctx->gf_ctx.graph); -	ctx->gf_ctx.graph = NULL; -        pthread_cancel (ctx->reply_thread); - -        FREE (ctx); - -        return 0; -} - - -int32_t  -libgf_client_lookup_cbk (call_frame_t *frame, -                         void *cookie, -                         xlator_t *this, -                         int32_t op_ret, -                         int32_t op_errno, -                         inode_t *inode, -                         struct iatt *buf, -                         dict_t *dict, -                         struct iatt *postparent) -{ -        libgf_client_local_t *local = frame->local; -        libglusterfs_client_ctx_t *ctx = frame->root->state; -	dict_t *xattr_req = NULL; - -        if (op_ret == 0) { -		inode_t *parent = NULL; - -		if (local->fop.lookup.loc->ino == 1) { -			buf->ia_ino = 1; -		} - -		parent = local->fop.lookup.loc->parent; -                if (inode->ino != 1) { -                        inode = inode_link (inode, parent, -                                            local->fop.lookup.loc->name, buf); -                } - -                libgf_transform_iattr (ctx, inode, buf); -		inode_lookup (inode); -        } else { -                if ((local->fop.lookup.is_revalidate == 0)  -                    && (op_errno == ENOENT)) { -                        gf_log ("libglusterfsclient", GF_LOG_DEBUG, -                                "%"PRId64": (op_num=%d) %s => -1 (%s)", -				frame->root->unique, frame->root->op, -				local->fop.lookup.loc->path, -				strerror (op_errno)); -                } else { -                        gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "%"PRId64": (op_num=%d) %s => -1 (%s)", -				frame->root->unique, frame->root->op, -				local->fop.lookup.loc->path, -				strerror (op_errno)); -                } - -                if (local->fop.lookup.is_revalidate == 1) { -			int32_t ret = 0; -                        inode_unref (local->fop.lookup.loc->inode); -                        local->fop.lookup.loc->inode = inode_new (ctx->itable); -                        local->fop.lookup.is_revalidate = 2; - -                        if (local->fop.lookup.size > 0) { -                                xattr_req = dict_new (); -                                ret = dict_set (xattr_req, "glusterfs.content", -                                                data_from_uint64 (local->fop.lookup.size)); -                                if (ret == -1) { -                                        op_ret = -1; -                                        /* TODO: set proper error code */ -                                        op_errno = errno; -                                        inode = NULL; -                                        buf = NULL; -                                        dict = NULL; -                                        dict_unref (xattr_req); -                                        goto out; -                                } -                        } - -                        STACK_WIND (frame, libgf_client_lookup_cbk, -                                    FIRST_CHILD (this), -                                    FIRST_CHILD (this)->fops->lookup, -                                    local->fop.lookup.loc, xattr_req); - -			if (xattr_req) { -				dict_unref (xattr_req); -				xattr_req = NULL; -			} - -                        return 0; -                } -        } - -out: -        local->reply_stub = fop_lookup_cbk_stub (frame, NULL, op_ret, op_errno, -                                                 inode, buf, dict, postparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int32_t -libgf_client_lookup (libglusterfs_client_ctx_t *ctx, -                     loc_t *loc, -                     struct iatt *stbuf, -                     dict_t **dict, -		     dict_t *xattr_req) -{ -        call_stub_t  *stub = NULL; -        int32_t op_ret; -        libgf_client_local_t *local = NULL; -        inode_t *inode = NULL; -         -        local = CALLOC (1, sizeof (*local)); -        if (!local) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Memory allocation" -                        " failed"); -                errno = ENOMEM; -                return -1; -        } - -        if (loc->inode) { -                local->fop.lookup.is_revalidate = 1; -                loc->ino = loc->inode->ino; -        } -        else -                loc->inode = inode_new (ctx->itable); - -        local->fop.lookup.loc = loc; - -        LIBGF_CLIENT_FOP(ctx, stub, lookup, local, loc, xattr_req); - -        op_ret = stub->args.lookup_cbk.op_ret; -        errno = stub->args.lookup_cbk.op_errno; - -        if (op_ret == -1) -                goto out; - -        inode = stub->args.lookup_cbk.inode; -        if (!(libgf_get_inode_ctx (inode))) -                libgf_alloc_inode_ctx (ctx, inode); -        libgf_transform_iattr (ctx, inode, &stub->args.lookup_cbk.buf); -        libgf_update_iattr_cache (inode, LIBGF_UPDATE_ALL, -                                        &stub->args.lookup_cbk.buf); -        if (stbuf) -                *stbuf = stub->args.lookup_cbk.buf; - -        if (dict) -                *dict = dict_ref (stub->args.lookup_cbk.dict); - -        if (inode != loc->inode) { -                inode_unref (loc->inode); -                loc->inode = inode_ref (inode); -        } - -out: -	call_stub_destroy (stub); -        return op_ret; -} - -int  -glusterfs_glh_get (glusterfs_handle_t handle, const char *path, void *buf, -                   size_t size, struct stat *stbuf) -{ -        int32_t op_ret = -1; -        loc_t loc = {0, }; -        libglusterfs_client_ctx_t *ctx = handle; -        dict_t *dict = NULL; -	dict_t *xattr_req = NULL; -	char *name = NULL, *pathname = NULL; -        struct iatt iatt = {0,}; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, size %lu", path, -                (long unsigned)size); -        if (size < 0) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Invalid size"); -                errno = EINVAL; -                goto out; -        } - -        if (size == 0) { -                op_ret = 0; -                goto out; -        } - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Path compaction failed"); -                goto out; -        } - -	op_ret = libgf_client_path_lookup (&loc, ctx, 0); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", GF_LOG_ERROR, -			"path lookup failed for (%s)", loc.path); -		goto out; -	} - -	pathname = strdup (loc.path); -	name = basename (pathname); - -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name); -        if (op_ret < 0) { -                gf_log ("libglusterfsclient", -                        GF_LOG_ERROR, -                        "libgf_client_loc_fill returned -1, returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        if (size) {  -                xattr_req = dict_new (); -                op_ret = dict_set (xattr_req, "glusterfs.content", -                                   data_from_uint64 (size)); -                if (op_ret < 0) { -                        gf_log ("libglusterfsclient", -                                GF_LOG_ERROR, -                                "setting requested content size dictionary failed"); -                        goto out; -                } -        } - -        op_ret = libgf_client_lookup (ctx, &loc, &iatt, &dict, xattr_req); -        iatt_to_stat (&iatt, stbuf); -        if (!op_ret && stbuf && (iatt.ia_size <= size) && dict && buf) { -                data_t *mem_data = NULL; -                void *mem = NULL; -                 -                mem_data = dict_get (dict, "glusterfs.content"); -                if (mem_data) { -                        mem = data_to_ptr (mem_data); -                } -                         -                if (mem != NULL) {  -                        memcpy (buf, mem, iatt.ia_size); -                } -        } - -out: -	if (xattr_req) { -		dict_unref (xattr_req); -	} -         -	if (dict) { -		dict_unref (dict); -	} - -	if (pathname) { -		FREE (pathname); -	} -	libgf_client_loc_wipe (&loc); - -        return op_ret; -} - -int -glusterfs_get (const char *path, void *buf, size_t size, struct stat *stbuf) -{ -        int                     op_ret = -1; -        glusterfs_handle_t      h      = NULL; -        char                    vpath[PATH_MAX]; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, buf, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, stbuf, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, size %lu", path, -                (long unsigned)size); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_get (h, vpath, buf, size, stbuf); - -out: -        return op_ret; -} - -int -libgf_client_lookup_async_cbk (call_frame_t *frame, -                               void *cookie, -                               xlator_t *this, -                               int32_t op_ret, -                               int32_t op_errno, -                               inode_t *inode, -                               struct iatt *stbuf, -                               dict_t *dict, -                               struct iatt *postparent) -{ -        libglusterfs_client_async_local_t *local = frame->local; -        glusterfs_get_cbk_t lookup_cbk = local->fop.lookup_cbk.cbk; -        libglusterfs_client_ctx_t *ctx = frame->root->state; -	glusterfs_iobuf_t *iobuf = NULL; -	dict_t *xattr_req = NULL; -        inode_t *parent = NULL; -        struct stat stat = {0,}; - -        if (op_ret == 0) { -                parent = local->fop.lookup_cbk.loc->parent; -                inode_link (inode, parent, local->fop.lookup_cbk.loc->name, -                            stbuf); -                libgf_transform_iattr (ctx, inode, stbuf); -                if (!(libgf_get_inode_ctx (inode))) -                        libgf_alloc_inode_ctx (ctx, inode); -                libgf_update_iattr_cache (inode, LIBGF_UPDATE_ALL, stbuf); -                inode_lookup (inode); -        } else { -                if ((local->fop.lookup_cbk.is_revalidate == 0)  -                    && (op_errno == ENOENT)) { -                        gf_log ("libglusterfsclient", GF_LOG_DEBUG, -                                "%"PRId64": (op_num=%d) %s => -1 (%s)", -				frame->root->unique, frame->root->op, -				local->fop.lookup_cbk.loc->path, -				strerror (op_errno)); -                } else { -                        gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "%"PRId64": (op_num=%d) %s => -1 (%s)", -				frame->root->unique, frame->root->op, -                                local->fop.lookup_cbk.loc->path, -				strerror (op_errno)); -                } - -                if (local->fop.lookup_cbk.is_revalidate == 1) { -			int32_t ret = 0; -                        inode_unref (local->fop.lookup_cbk.loc->inode); -                        local->fop.lookup_cbk.loc->inode = inode_new (ctx->itable); -                        local->fop.lookup_cbk.is_revalidate = 2; - -                        if (local->fop.lookup_cbk.size > 0) { -                                xattr_req = dict_new (); -                                ret = dict_set (xattr_req, "glusterfs.content", -                                                data_from_uint64 (local->fop.lookup_cbk.size)); -                                if (ret == -1) { -                                        op_ret = -1; -                                        /* TODO: set proper error code */ -                                        op_errno = errno; -                                        inode = NULL; -                                        stbuf = NULL; -                                        dict = NULL; -                                        dict_unref (xattr_req); -                                        goto out; -                                } -                        } - - -                        STACK_WIND (frame, libgf_client_lookup_async_cbk, -                                    FIRST_CHILD (this), -                                    FIRST_CHILD (this)->fops->lookup, -                                    local->fop.lookup_cbk.loc, xattr_req); -			 -			if (xattr_req) { -				dict_unref (xattr_req); -				xattr_req = NULL; -			} - -                        return 0; -                } -        } - -out: -        if (!op_ret && local->fop.lookup_cbk.size && dict) { -                data_t *mem_data = NULL; -                void *mem = NULL; -		struct iovec *vector = NULL; - -                mem_data = dict_get (dict, "glusterfs.content"); -                if (mem_data) { -                        mem = data_to_ptr (mem_data); -                } - -                if (mem && stbuf->ia_size <= local->fop.lookup_cbk.size) { -			iobuf = CALLOC (1, sizeof (*iobuf)); -			ERR_ABORT (iobuf); - -			vector = CALLOC (1, sizeof (*vector)); -			ERR_ABORT (vector); -			vector->iov_base = mem; -			vector->iov_len = stbuf->ia_size;   - -			iobuf->vector = vector; -			iobuf->count = 1; -			iobuf->dictref = dict_ref (dict); -		} -	} - -        iatt_to_stat (stbuf, &stat); -        lookup_cbk (op_ret, op_errno, iobuf, &stat, local->cbk_data); - -	libgf_client_loc_wipe (local->fop.lookup_cbk.loc); -        free (local->fop.lookup_cbk.loc); - -        free (local); -        frame->local = NULL; -        STACK_DESTROY (frame->root); - -        return 0; -} - -/* TODO: implement async dentry lookup */ - -int -glusterfs_get_async (glusterfs_handle_t handle,  -		     const char *path, -		     size_t size,  -		     glusterfs_get_cbk_t cbk, -		     void *cbk_data) -{ -        loc_t *loc = NULL; -        libglusterfs_client_ctx_t *ctx = handle; -        libglusterfs_client_async_local_t *local = NULL; -	int32_t op_ret = 0; -	dict_t *xattr_req = NULL; -	char *name = NULL, *pathname = NULL; - -	if (!ctx || !path || path[0] != '/') { -		errno = EINVAL; -		op_ret = -1; -		goto out; -	} - -        if (size < 0) { -                errno = EINVAL; -                op_ret = -1; -                goto out; -        } - -        if (size == 0) { -                op_ret = 0; -                goto out; -        } - -        local = CALLOC (1, sizeof (*local)); -        local->fop.lookup_cbk.is_revalidate = 1; - -        loc = CALLOC (1, sizeof (*loc)); -	loc->path = strdup (path); -	op_ret = libgf_client_path_lookup (loc, ctx, 1); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"path lookup failed for (%s)", path); -		goto out; -	} - -	pathname = strdup (path); -	name = basename (pathname); -        op_ret = libgf_client_loc_fill (loc, ctx, 0, loc->parent->ino, name); -	if (op_ret < 0) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} - -        if (!loc->inode) { -                loc->inode = inode_new (ctx->itable); -                local->fop.lookup_cbk.is_revalidate = 0; -        }  - -        local->fop.lookup_cbk.cbk = cbk; -        local->fop.lookup_cbk.size = size; -        local->fop.lookup_cbk.loc = loc; -        local->cbk_data = cbk_data; - -        if (size > 0) { -                xattr_req = dict_new (); -                op_ret = dict_set (xattr_req, "glusterfs.content", -                                   data_from_uint64 (size)); -                if (op_ret < 0) { -                        dict_unref (xattr_req); -                        xattr_req = NULL; -                        goto out; -                } -        } - -        LIBGF_CLIENT_FOP_ASYNC (ctx, -                                local, -                                libgf_client_lookup_async_cbk, -                                lookup, -                                loc, -                                xattr_req); -	if (xattr_req) { -		dict_unref (xattr_req); -		xattr_req = NULL; -	} - -out: -	if (pathname) { -		FREE (pathname); -	} -  -        return op_ret; -} - -int32_t -libgf_client_getxattr_cbk (call_frame_t *frame, -                           void *cookie, -                           xlator_t *this, -                           int32_t op_ret, -                           int32_t op_errno, -                           dict_t *dict) -{ - -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_getxattr_cbk_stub (frame, NULL, op_ret, -                                                   op_errno, dict); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -size_t  -libgf_client_getxattr (libglusterfs_client_ctx_t *ctx,  -                       loc_t *loc, -                       const char *name, -                       void *value, -                       size_t size) -{ -        call_stub_t  *stub = NULL; -        int32_t op_ret = 0; -        libgf_client_local_t *local = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, getxattr, local, loc, name); - -        op_ret = stub->args.getxattr_cbk.op_ret; -        errno = stub->args.getxattr_cbk.op_errno; - -        if (op_ret >= 0) { -                /* -                  gf_log ("LIBGF_CLIENT", GF_LOG_DEBUG, -                  "%"PRId64": %s => %d", frame->root->unique, -                  state->fuse_loc.loc.path, op_ret); -                */ - -                data_t *value_data = dict_get (stub->args.getxattr_cbk.dict, -                                               (char *)name); -     -                if (value_data) { -                        int32_t copy_len = 0; - -                        /* Don't return the value for '\0' */ -                        op_ret = value_data->len;  -                        if ((size > 0) && (value != NULL)) { -                                copy_len = size < value_data->len ?  -                                        size : value_data->len; -                                memcpy (value, value_data->data, copy_len); -                                op_ret = copy_len; -                        } -                } else { -                        errno = ENODATA; -                        op_ret = -1; -                } -        } -	 -	call_stub_destroy (stub); -        return op_ret; -} - -#define LIBGF_DO_GETXATTR       1 -#define LIBGF_DO_LGETXATTR      2 - -ssize_t -__glusterfs_glh_getxattr (glusterfs_handle_t handle, const char *path, -                          const char *name, void *value, size_t size, -                          int whichop) -{ -        int32_t op_ret = -1; -        loc_t loc = {0, }; -	libglusterfs_client_ctx_t *ctx = handle; -	char *file = NULL; -        char *pathres = NULL, *tmp = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, name, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, name %s, size %lu," -                " op %d", path, name, (long unsigned)size, whichop); -        if (name[0] == '\0') { -		errno = EINVAL; -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Invalid argument: Name" -                        " not NULL terminated"); -		goto out; -	} - -        if (size < 0) { -                errno = EINVAL; -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Invalid argument: size is" -                        " less than zero"); -                goto out; -        } - -        pathres = strdup (path); -        if (!pathres) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        loc.path = strdup (pathres); -	op_ret = libgf_client_path_lookup (&loc, ctx, 1); -	if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -			"path lookup failed for (%s)", loc.path); -		goto out; -	} - -	tmp = strdup (pathres); -	file = basename (tmp); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, file); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} - -        if (whichop == LIBGF_DO_LGETXATTR) -                goto do_getx; - -        if (!IA_ISLNK (loc.inode->ia_type)) -                goto do_getx; - -        libgf_client_loc_wipe (&loc);  -        op_ret = libgf_realpath_loc_fill (ctx, (char *)pathres, &loc); -        if (op_ret == -1) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "realpath failed"); -                goto out; -        } - -do_getx: -	op_ret = libgf_client_getxattr (ctx, &loc, name, value, size); - -out: -	if (tmp) { -		FREE (tmp); -	} - -        if (pathres) -                FREE (pathres); - -        libgf_client_loc_wipe (&loc); - -        return op_ret; -} - -ssize_t -glusterfs_glh_getxattr (glusterfs_handle_t handle, const char *path, -                        const char *name, void *value, size_t size) -{ -        return __glusterfs_glh_getxattr (handle, path, name, value, size, -                                         LIBGF_DO_GETXATTR); -} - -ssize_t -glusterfs_glh_lgetxattr (glusterfs_handle_t handle, const char *path, -                         const char *name, void *value, size_t size) -{ -        return __glusterfs_glh_getxattr (handle, path, name, value, size, -                                         LIBGF_DO_LGETXATTR); -} - -ssize_t -glusterfs_getxattr (const char *path, const char *name, void *value, -                        size_t size) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, name, out); - -        if ((size > 0) && (value == NULL)) { -                errno = EINVAL; -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Invalid argument value"); -                goto out; -        } - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, name %s, size %lu", -                path, name, (long unsigned)size); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = __glusterfs_glh_getxattr (h, vpath, name, value, size, -                                           LIBGF_DO_GETXATTR); - -out: -        return op_ret; -} - -ssize_t -glusterfs_lgetxattr (const char *path, const char *name, void *value, -                     size_t size) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, name, out); - -        if ((size > 0) && (value == NULL)) { -                errno = EINVAL; -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Invalid argument value"); -                goto out; -        } - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, name %s, size %lu", -                path, name, (long unsigned)size); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = __glusterfs_glh_getxattr (h, vpath, name, value, size, -                                           LIBGF_DO_LGETXATTR); - -out: -        return op_ret; -} - -static int32_t -libgf_client_open_cbk (call_frame_t *frame, -                       void *cookie, -                       xlator_t *this, -                       int32_t op_ret, -                       int32_t op_errno, -                       fd_t *fd) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_open_cbk_stub (frame, NULL, op_ret, op_errno, -                                               fd); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - - -int  -libgf_client_open (libglusterfs_client_ctx_t *ctx,  -                   loc_t *loc,  -                   fd_t *fd,  -                   int flags) -{ -        call_stub_t *stub = NULL; -        int32_t op_ret = 0; -        libgf_client_local_t *local = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, open, local, loc, flags, fd, 0); - -        op_ret = stub->args.open_cbk.op_ret; -        errno = stub->args.open_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "open: path %s, status: %d, errno" -                " %d", loc->path, op_ret, errno); -        if (op_ret != -1) -                fd_bind (fd); -	call_stub_destroy (stub); -        return op_ret; -} - -static int32_t -libgf_client_create_cbk (call_frame_t *frame, -                         void *cookie, -                         xlator_t *this, -                         int32_t op_ret, -                         int32_t op_errno, -                         fd_t *fd, -                         inode_t *inode, -                         struct iatt *buf, -                         struct iatt *preparent, -                         struct iatt *postparent) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_create_cbk_stub (frame, NULL, op_ret, op_errno, -                                                 fd, inode, buf, preparent, -                                                 postparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int  -libgf_client_creat (libglusterfs_client_ctx_t *ctx, -                    loc_t *loc, -                    fd_t *fd, -                    int flags, -                    mode_t mode) -{ -        call_stub_t *stub = NULL; -        int32_t op_ret = 0; -        libgf_client_local_t *local = NULL; -        inode_t *libgf_inode = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, create, local, loc, flags, mode, fd); -   -        op_ret = stub->args.create_cbk.op_ret; -        errno = stub->args.create_cbk.op_errno; -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Create: path %s, status: %d," -                " errno: %d", loc->path, op_ret, errno); -        if (op_ret == -1) -                goto out; - -	libgf_inode = stub->args.create_cbk.inode; -        inode_link (libgf_inode, loc->parent, loc->name, -                        &stub->args.create_cbk.buf); -        libgf_transform_iattr (ctx, libgf_inode, &stub->args.create_cbk.buf); - -        inode_lookup (libgf_inode); - -        libgf_alloc_inode_ctx (ctx, libgf_inode); -        libgf_update_iattr_cache (libgf_inode, LIBGF_UPDATE_ALL, -                                        &stub->args.create_cbk.buf); - -out: -	call_stub_destroy (stub); -        return op_ret; -} - -int32_t -libgf_client_opendir_cbk (call_frame_t *frame, -                          void *cookie, -                          xlator_t *this, -                          int32_t op_ret, -                          int32_t op_errno, -                          fd_t *fd) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_opendir_cbk_stub (frame, NULL, op_ret, op_errno, -                                                  fd); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int  -libgf_client_opendir (libglusterfs_client_ctx_t *ctx, -                      loc_t *loc, -                      fd_t *fd) -{ -        call_stub_t *stub = NULL; -        int32_t op_ret = -1; -        libgf_client_local_t *local = NULL; - -        if (((fd->flags & O_ACCMODE) == O_WRONLY) -                || ((fd->flags & O_ACCMODE) == O_RDWR)) { -                errno = EISDIR; -                goto out; -        } -        LIBGF_CLIENT_FOP (ctx, stub, opendir, local, loc, fd); - -        op_ret = stub->args.opendir_cbk.op_ret; -        errno = stub->args.opendir_cbk.op_errno; -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "opendir: path %s, status %d," -                " errno %d", loc->path, op_ret, errno); -        if (op_ret != -1) -                fd_bind (fd); - -	call_stub_destroy (stub); -out: -        return op_ret; -} - -glusterfs_file_t  -glusterfs_glh_open (glusterfs_handle_t handle, const char *path, int flags,...) -{ -        loc_t loc = {0, }; -        long op_ret = -1; -        fd_t *fd = NULL; -	int32_t ret = -1; -	libglusterfs_client_ctx_t *ctx = handle; -	char *name = NULL, *pathname = NULL; -        libglusterfs_client_inode_ctx_t *inode_ctx = NULL; -        mode_t mode = 0; -        va_list ap; -        char *pathres = NULL; -        char *vpath = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        pathres = strdup (path); -        if (!pathres) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -	loc.path = strdup (pathres); -	op_ret = libgf_client_path_lookup (&loc, ctx, 1); - -        if ((op_ret == -1) && ((flags & O_CREAT) != O_CREAT)) { -		gf_log ("libglusterfsclient", GF_LOG_ERROR, -			"path lookup failed for (%s)", loc.path); -		goto out; -	} - -        if (!op_ret && ((flags & O_CREAT) == O_CREAT)  -            && ((flags & O_EXCL) == O_EXCL)) { -                errno = EEXIST; -                op_ret = -1; -                goto out; -        } - -        if (op_ret == 0) { -                flags &= ~O_CREAT; -        } - -        if ((op_ret == -1) && ((flags & O_CREAT) == O_CREAT)) { -                libgf_client_loc_wipe (&loc); -                loc.path = strdup (pathres); - -                op_ret = libgf_client_path_lookup (&loc, ctx, 0); -                if (op_ret == -1) { -                        gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "path lookup failed for parent while trying to" -                                " create (%s)", pathres); -                        goto out; -                } - -                loc.inode = inode_new (ctx->itable); -        } - -	pathname = strdup (pathres); -	name = basename (pathname); - -        ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name); -	if (ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} - -        fd = fd_create (loc.inode, ctx->pid); -        fd->flags = flags; - -        if (((flags & O_CREAT) == O_CREAT)) { -                /* If we have the st_mode for the basename, check if -                 * it is a directory here itself, rather than sending -                 * a network message through libgf_client_creat, and -                 * then receiving a EISDIR. -                 */ -                if (IA_ISDIR (loc.inode->ia_type)) { -                        errno = EISDIR; -                        op_ret = -1; -                        goto op_over; -                } -                va_start (ap, flags); -                mode = va_arg (ap, mode_t); -                va_end (ap); -                op_ret = libgf_client_creat (ctx, &loc, fd, flags, mode); -        } else { -                if (IA_ISDIR (loc.inode->ia_type)) -                        op_ret = libgf_client_opendir (ctx, &loc, fd); -                else -                        op_ret = libgf_client_open (ctx, &loc, fd, flags); -        } - -op_over: -        if (op_ret == -1) { -                fd_unref (fd); -                fd = NULL; -                goto out; -        } - -        vpath = NULL; -        if (IA_ISDIR (loc.inode->ia_type)) { -                vpath = (char *)path; -        } - -        if (!libgf_get_fd_ctx (fd)) { -                if (!libgf_alloc_fd_ctx (ctx, fd, vpath)) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Failed to" -                                " allocate fd context"); -                        errno = EINVAL; -                        op_ret = -1; -                        goto out; -                } -        } - -        if ((flags & O_TRUNC) && (((flags & O_ACCMODE) == O_RDWR) -                                  || ((flags & O_ACCMODE) == O_WRONLY))) { -                inode_ctx = libgf_get_inode_ctx (fd->inode); -                if (IA_ISREG (inode_ctx->stbuf.ia_type)) { -                                inode_ctx->stbuf.ia_size = 0; -                                inode_ctx->stbuf.ia_blocks = 0; -                } -        } - -out: -        libgf_client_loc_wipe (&loc); - -	if (pathname) { -		FREE (pathname); -	} - -        if (pathres) -                FREE (pathres); - -        return fd; -} - -glusterfs_file_t -glusterfs_open (const char *path, int flags, ...) -{ -        va_list                 ap; -        glusterfs_file_t        fh   = NULL; -        glusterfs_handle_t      h    = NULL;  -        mode_t                  mode = 0; -        char                    vpath[PATH_MAX]; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        if (flags & O_CREAT) { -                va_start (ap, flags); -                mode = va_arg (ap, mode_t); -                va_end (ap); -                fh = glusterfs_glh_open (h, vpath, flags, mode); -        } else -                fh = glusterfs_glh_open (h, vpath, flags); -out: -        return fh; -} - -glusterfs_file_t  -glusterfs_glh_creat (glusterfs_handle_t handle, const char *path, mode_t mode) -{ -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); -	return glusterfs_glh_open (handle, path, -			       (O_CREAT | O_WRONLY | O_TRUNC), mode); -} - -glusterfs_file_t -glusterfs_creat (const char *path, mode_t mode) -{ -        glusterfs_file_t        fh = NULL; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        fh = glusterfs_glh_creat (h, vpath, mode); - -out: -        return fh; -} - -int32_t -libgf_client_flush_cbk (call_frame_t *frame, -                        void *cookie, -                        xlator_t *this, -                        int32_t op_ret, -                        int32_t op_errno) -{ -        libgf_client_local_t *local = frame->local; -         -        local->reply_stub = fop_flush_cbk_stub (frame, NULL, op_ret, op_errno); -         -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - - -int  -libgf_client_flush (libglusterfs_client_ctx_t *ctx, fd_t *fd) -{ -        call_stub_t *stub; -        int32_t op_ret; -        libgf_client_local_t *local = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, flush, local, fd); -         -        op_ret = stub->args.flush_cbk.op_ret; -        errno = stub->args.flush_cbk.op_errno; -         -	call_stub_destroy (stub);         -        return op_ret; -} - - -int  -glusterfs_close (glusterfs_file_t fd) -{ -        int32_t op_ret = -1; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        if (!fd) { -                errno = EINVAL; -		goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                goto out; -        } -        ctx = fd_ctx->ctx; - -        op_ret = libgf_client_flush (ctx, (fd_t *)fd); - -        fd_unref ((fd_t *)fd); - -out: -        return op_ret; -} - -int32_t -libgf_client_setxattr_cbk (call_frame_t *frame, -                           void *cookie, -                           xlator_t *this, -                           int32_t op_ret, -                           int32_t op_errno) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_setxattr_cbk_stub (frame, NULL, op_ret, -                                                   op_errno); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int -libgf_client_setxattr (libglusterfs_client_ctx_t *ctx,  -                       loc_t *loc, -                       const char *name, -                       const void *value, -                       size_t size, -                       int flags) -{ -        call_stub_t  *stub = NULL; -        int32_t op_ret = 0; -        dict_t *dict; -        libgf_client_local_t *local = NULL; - -        dict = get_new_dict (); - -        dict_set (dict, (char *)name, -                  bin_to_data ((void *)value, size)); -        dict_ref (dict); - - -        LIBGF_CLIENT_FOP (ctx, stub, setxattr, local, loc, dict, flags); - -        op_ret = stub->args.setxattr_cbk.op_ret; -        errno = stub->args.setxattr_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "path %s, name %s, status %d," -                "errno %d", loc->path, name, op_ret, errno); -        dict_unref (dict); -	call_stub_destroy (stub); -        return op_ret; -} - - -#define LIBGF_DO_SETXATTR       1 -#define LIBGF_DO_LSETXATTR      2 - -int  -__glusterfs_glh_setxattr (glusterfs_handle_t handle, const char *path, -                          const char *name, const void *value, -                          size_t size, int flags, int whichop) -{ -        int32_t op_ret = -1; -        loc_t loc = {0, }; -	libglusterfs_client_ctx_t *ctx = handle; -        char *tmppath = NULL; -        loc_t *realloc = NULL; -        char *pathres = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "path %s, name %s, op %d", path -                ,name, whichop); -        if (size <= 0) { -                errno = EINVAL; -                goto out; -        } - -        pathres = strdup (path); -        if (!pathres) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        loc.path = strdup (pathres); -	op_ret = libgf_client_path_lookup (&loc, ctx, 1); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", GF_LOG_ERROR, -			"path lookup failed for (%s)", pathres); -		goto out; -	} - -        tmppath = strdup (pathres); - -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                        basename (tmppath)); -        FREE (tmppath); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} - -        realloc = &loc; -        if (whichop == LIBGF_DO_LSETXATTR) -                goto do_setx; - -        if (!IA_ISLNK (loc.inode->ia_type)) -                goto do_setx; - -        libgf_client_loc_wipe (&loc); -        realloc = &loc; -        libgf_realpath_loc_fill (ctx, (char *)pathres, realloc); - -do_setx: -        if (!op_ret) -                op_ret = libgf_client_setxattr (ctx, realloc, name, value, -                                                size, flags); - -out: -        if (pathres) -                FREE (pathres); - -        libgf_client_loc_wipe (realloc); -        return op_ret; -} - -int -glusterfs_glh_setxattr (glusterfs_handle_t handle, const char *path, -                        const char *name, const void *value, size_t size, -                        int flags) -{ -        return __glusterfs_glh_setxattr (handle, path, name, value, size, flags -                                         , LIBGF_DO_SETXATTR); -} - -int -glusterfs_glh_lsetxattr (glusterfs_handle_t handle, const char *path, -                         const char *name, const void *value, size_t size, -                         int flags) -{ -        return __glusterfs_glh_setxattr (handle, path, name, value, size, flags -                                         , LIBGF_DO_LSETXATTR); -} - -int -glusterfs_setxattr (const char *path, const char *name, const void *value, -                        size_t size, int flags) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, name, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, value, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "path %s, name %s", path, name); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = __glusterfs_glh_setxattr (h, vpath, name, value, size, flags, -                                           LIBGF_DO_SETXATTR); - -out: -        return op_ret; -} - -int -glusterfs_lsetxattr (const char *path, const char *name, const void *value, -                     size_t size, int flags) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, name, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, value, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "path %s, name %s", path, name); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = __glusterfs_glh_setxattr (h, vpath, name, value, size, flags, -                                           LIBGF_DO_LSETXATTR); - -out: -        return op_ret; -} - -int32_t -libgf_client_fsetxattr_cbk (call_frame_t *frame, -                            void *cookie, -                            xlator_t *this, -                            int32_t op_ret, -                            int32_t op_errno) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_fsetxattr_cbk_stub (frame, NULL, op_ret, -                                                    op_errno); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int -libgf_client_fsetxattr (libglusterfs_client_ctx_t *ctx,  -                        fd_t *fd, -                        const char *name, -                        const void *value, -                        size_t size, -                        int flags) -{ -        call_stub_t  *stub = NULL; -        int32_t op_ret = 0; -        dict_t *dict; -        libgf_client_local_t *local = NULL; - -        dict = get_new_dict (); - -        dict_set (dict, (char *)name, -                  bin_to_data ((void *)value, size)); -        dict_ref (dict); - -        LIBGF_CLIENT_FOP (ctx, stub, fsetxattr, local, fd, dict, flags); - -        op_ret = stub->args.fsetxattr_cbk.op_ret; -        errno = stub->args.fsetxattr_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "name %s, status %d, errno %d", -                name, op_ret, errno); -        dict_unref (dict); -	call_stub_destroy (stub); - -        return op_ret; -} - -int  -glusterfs_fsetxattr (glusterfs_file_t fd,  -                     const char *name, -                     const void *value,  -                     size_t size,  -                     int flags) -{ -	int32_t op_ret = 0; -        fd_t *__fd = fd; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -        libglusterfs_client_ctx_t *ctx = NULL; -         -        if (!fd) { -                errno = EINVAL; -                op_ret = -1; -                gf_log("libglusterfsclient", -                       GF_LOG_ERROR, -                       "invalid fd"); -                goto out; -        } - -        if (size <= 0) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Invalid argument: size is" -                        " less than or equal to zero"); -                errno = EINVAL; -                op_ret = -1; -                goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -		op_ret = -1; -		goto out; -        } - -        ctx = fd_ctx->ctx; -        op_ret = libgf_client_fsetxattr (ctx, __fd, name, value, size, -                                         flags); -         -out: -	return op_ret; -} - -int32_t -libgf_client_fgetxattr_cbk (call_frame_t *frame, -                            void *cookie, -                            xlator_t *this, -                            int32_t op_ret, -                            int32_t op_errno, -                            dict_t *dict) -{ - -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_fgetxattr_cbk_stub (frame, NULL, op_ret, -                                                    op_errno, dict); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -size_t  -libgf_client_fgetxattr (libglusterfs_client_ctx_t *ctx,  -                        fd_t *fd, -                        const char *name, -                        void *value, -                        size_t size) -{ -        call_stub_t  *stub = NULL; -        int32_t op_ret = 0; -        libgf_client_local_t *local = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, fgetxattr, local, fd, name); - -        op_ret = stub->args.fgetxattr_cbk.op_ret; -        errno = stub->args.fgetxattr_cbk.op_errno; - -        if (op_ret >= 0) { -                /* -                  gf_log ("LIBGF_CLIENT", GF_LOG_DEBUG, -                  "%"PRId64": %s => %d", frame->root->unique, -                  state->fuse_loc.loc.path, op_ret); -                */ - -                data_t *value_data = dict_get (stub->args.fgetxattr_cbk.dict, -                                               (char *)name); -     -                if (value_data) { -                        int32_t copy_len = 0; - -                        /* Don't return the value for '\0' */ -                        op_ret = value_data->len;  -                        copy_len = size < value_data->len ?  -                                size : value_data->len; -                        memcpy (value, value_data->data, copy_len); -                } else { -                        errno = ENODATA; -                        op_ret = -1; -                } -        } -	 -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "name %s, status %d, errno %d", -                name, op_ret, errno); -	call_stub_destroy (stub); -        return op_ret; -} - -ssize_t  -glusterfs_fgetxattr (glusterfs_file_t fd,  -                     const char *name, -                     void *value,  -                     size_t size) -{ -	int32_t op_ret = 0; -        libglusterfs_client_ctx_t *ctx; -        fd_t *__fd = (fd_t *)fd; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "name %s", name); -        if (size < 0) { -                errno = EINVAL; -                op_ret = -1; -                goto out; -        } - -        if (size == 0) -                goto out; - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -		op_ret = -1; -		goto out; -        } - -        ctx = fd_ctx->ctx; -        op_ret = libgf_client_fgetxattr (ctx, __fd, name, value, size); -out: -	return op_ret; -} - -ssize_t  -glusterfs_listxattr (glusterfs_handle_t handle, -                     const char *path,  -                     char *list, -                     size_t size) -{ -        return ENOSYS; -} - -ssize_t  -glusterfs_llistxattr (glusterfs_handle_t handle, -                      const char *path,  -                      char *list, -                      size_t size) -{ -        return ENOSYS; -} - -ssize_t  -glusterfs_flistxattr (glusterfs_file_t fd,  -                      char *list, -                      size_t size) -{ -        return ENOSYS; -} - -int  -glusterfs_removexattr (glusterfs_handle_t handle,  -                       const char *path,  -                       const char *name) -{ -        return ENOSYS; -} - -int  -glusterfs_lremovexattr (glusterfs_handle_t handle,  -                        const char *path,  -                        const char *name) -{ -        return ENOSYS; -} - -int  -glusterfs_fremovexattr (glusterfs_file_t fd,  -                        const char *name) -{ -        return ENOSYS; -} - -int32_t -libgf_client_readv_cbk (call_frame_t *frame, -                        void *cookie, -                        xlator_t *this, -                        int32_t op_ret, -                        int32_t op_errno, -                        struct iovec *vector, -                        int32_t count, -                        struct iatt *stbuf, -                        struct iobref *iobref) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_readv_cbk_stub (frame, NULL, op_ret, op_errno, -                                                vector, count, stbuf, iobref); -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int -libgf_client_iobuf_read (libglusterfs_client_ctx_t *ctx, fd_t *fd, void *buf, -                         size_t size, off_t offset) -{ -        call_stub_t          *stub = NULL; -        struct iovec         *vector = NULL; -        int32_t               op_ret = -1; -        int                   count = 0; -        libgf_client_local_t *local = NULL; -        struct iatt          *stbuf = NULL; - -        local = CALLOC (1, sizeof (*local)); -        ERR_ABORT (local); -        local->fd = fd; -        LIBGF_CLIENT_FOP (ctx, stub, readv, local, fd, size, offset); - -        op_ret = stub->args.readv_cbk.op_ret; -        errno = stub->args.readv_cbk.op_errno; -        count = stub->args.readv_cbk.count; -        vector = stub->args.readv_cbk.vector; -        if (op_ret > 0) { -                int i = 0; -                op_ret = 0; -                while (size && (i < count)) { -                        int len = (size < vector[i].iov_len) ? -                                size : vector[i].iov_len; -                        memcpy (buf, vector[i++].iov_base, len); -                        buf += len; -                        size -= len; -                        op_ret += len; -                } -                stbuf = &stub->args.readv_cbk.stbuf; -                libgf_transform_iattr (ctx, fd->inode, stbuf); -                libgf_invalidate_iattr_cache (fd->inode, LIBGF_INVALIDATE_STAT); -        } - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "size %lu, offset %"PRIu64, -                (long unsigned)size, offset); -	call_stub_destroy (stub); -        return op_ret; -} - -int -libgf_client_read (libglusterfs_client_ctx_t *ctx, fd_t *fd, void *buf, -                   size_t size, off_t offset) -{ -        int32_t op_ret = -1; -        int32_t ret = 0; -        size_t  tmp   = 0; - -        while (size != 0) { -                tmp = ((size > LIBGF_IOBUF_SIZE) ? LIBGF_IOBUF_SIZE : -                       size); -                op_ret = libgf_client_iobuf_read (ctx, fd, buf, tmp, offset); -                if (op_ret < 0) { -                        ret = op_ret; -                        break; -                } - -                ret += op_ret; - -                if (op_ret < tmp) -                        break; - -                size -= op_ret; -                offset += op_ret; -                buf = (char *)buf + op_ret; -        } - -        return ret; -} - -ssize_t -glusterfs_read (glusterfs_file_t fd, void *buf, size_t nbytes) -{ -        int32_t op_ret = -1; -        off_t offset = 0; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        if (nbytes < 0) { -                errno = EINVAL; -                goto out; -        } - -        if (nbytes == 0) { -                op_ret = 0; -                goto out; -        } - -        if (fd == 0) { -                errno = EINVAL; -		goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -		goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                ctx = fd_ctx->ctx; -                offset = fd_ctx->offset; -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -        op_ret = libgf_client_read (ctx, (fd_t *)fd, buf, nbytes, offset); - -        if (op_ret > 0) { -                offset += op_ret; -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        fd_ctx->offset = offset; -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -out: -        return op_ret; -} - - -ssize_t -libgf_client_iobuf_readv (libglusterfs_client_ctx_t *ctx, fd_t *fd, -                          const struct iovec *dst_vector, int count, -                          size_t size, off_t offset, int *idx, -                          off_t *vec_offset) -{ -        call_stub_t          *stub       = NULL; -        struct iovec         *src_vector = NULL; -        int32_t               op_ret     = -1; -        libgf_client_local_t *local      = NULL; -        int                   src        = 0, dst = 0; -        int                   src_count  = 0, dst_count = 0; -        int                   len        = 0, src_len = 0, dst_len = 0; -        off_t                 src_offset = 0, dst_offset = 0; -        struct iatt          *stbuf      = NULL; - -        dst = *idx; -        dst_offset = *vec_offset; - -        local = CALLOC (1, sizeof (*local)); -        ERR_ABORT (local); -        local->fd = fd; -        LIBGF_CLIENT_FOP (ctx, stub, readv, local, fd, size, offset); - -        op_ret = stub->args.readv_cbk.op_ret; -        errno = stub->args.readv_cbk.op_errno; -        src_count = stub->args.readv_cbk.count; -        src_vector = stub->args.readv_cbk.vector; -        if (op_ret > 0) { -                while ((size != 0) && (dst < dst_count) && (src < src_count)) { -                        src_len = src_vector[src].iov_len - src_offset; -                        dst_len = dst_vector[dst].iov_len - dst_offset; - -                        len = (src_len < dst_len) ? src_len : dst_len; -                        if (len > size) { -                                len = size; -                        } - -                        memcpy (dst_vector[dst].iov_base + dst_offset, -				src_vector[src].iov_base + src_offset, len); - -                        size -= len; -                        src_offset += len; -                        dst_offset += len; - -                        if (src_offset == src_vector[src].iov_len) { -                                src_offset = 0; -                                src++; -                        } - -                        if (dst_offset == dst_vector[dst].iov_len) { -                                dst_offset = 0; -                                dst++; -                        } -                } - -                stbuf = &stub->args.readv_cbk.stbuf; -                libgf_transform_iattr (ctx, fd->inode, stbuf); -                libgf_invalidate_iattr_cache (fd->inode, LIBGF_UPDATE_STAT); -        } - -        *idx = dst; -        *vec_offset = dst_offset; - -	call_stub_destroy (stub); -        return op_ret; -} - - -ssize_t -libgf_client_readv (libglusterfs_client_ctx_t *ctx, fd_t *fd, -                    const struct iovec *dst_vector, int dst_count, off_t offset) -{ -        int32_t               op_ret     = -1; -        size_t                size       = 0, tmp = 0, ret = 0; -        int                   i          = 0; -        int                   dst_idx    = 0; -        off_t                 dst_offset = 0; - -        for (i = 0; i < dst_count; i++) -        { -                size += dst_vector[i].iov_len; -        } - -        while (size != 0) { -                tmp = ((size > LIBGF_IOBUF_SIZE) ? LIBGF_IOBUF_SIZE : size); -                op_ret = libgf_client_iobuf_readv (ctx, fd, dst_vector, -                                                   dst_count, tmp, offset, -                                                   &dst_idx, &dst_offset); -                if (op_ret <= 0) { -                        break; -                } - -                offset += op_ret; -                size -= op_ret; -                ret += op_ret; -        } - -        return ret; -} - - -ssize_t -glusterfs_readv (glusterfs_file_t fd, const struct iovec *vec, int count) -{ -        int32_t op_ret = -1; -        off_t offset = 0; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        if (count < 0) { -                errno = EINVAL; -                goto out; -        } - -        if (count == 0) { -                op_ret = 0; -                goto out; -        } - -        if (!fd) { -                errno = EINVAL; -		goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                ctx = fd_ctx->ctx; -                offset = fd_ctx->offset; -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -        op_ret = libgf_client_readv (ctx, (fd_t *)fd, vec, count, offset); - -        if (op_ret > 0) { -                offset += op_ret; -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        fd_ctx->offset = offset; -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -out: -        return op_ret; -} - - -ssize_t  -glusterfs_pread (glusterfs_file_t fd,  -                 void *buf,  -                 size_t count,  -                 off_t offset) -{ -        int32_t op_ret = -1; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        if (count < 0) { -                errno = EINVAL; -                goto out; -        } - -        if (count == 0) { -                op_ret = 0; -                goto out; -        } - -        if (!fd) { -                errno = EINVAL; -		goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        ctx = fd_ctx->ctx; - -        op_ret = libgf_client_read (ctx, (fd_t *)fd, buf, count, offset); - -out: -        return op_ret; -} - - -int -libgf_client_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) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_writev_cbk_stub (frame, NULL, op_ret, op_errno, -                                                 prebuf, postbuf); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - - -int -libgf_client_iobuf_write (libglusterfs_client_ctx_t *ctx, fd_t *fd, char *addr, -                          size_t size, off_t offset) -{ -        struct iobref        *ioref = NULL; -        struct iobuf         *iob = NULL; -        int                   op_ret = -1; -        struct iovec          iov = {0, }; -        call_stub_t          *stub = NULL; -        libgf_client_local_t *local = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, addr, out); - -        ioref = iobref_new (); -        if (!ioref) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Out of memory"); -                goto out; -        } - -        iob = iobuf_get (ctx->gf_ctx.iobuf_pool); -        if (!iob) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Out of memory"); -                goto out; -        } - -        memcpy (iob->ptr, addr, size); -        iobref_add (ioref, iob); - -        iov.iov_base = iob->ptr; -        iov.iov_len = size; - -        LIBGF_CLIENT_FOP (ctx, stub, writev, local, fd, &iov, -                          1, offset, ioref); - -        op_ret = stub->args.writev_cbk.op_ret; -        errno = stub->args.writev_cbk.op_errno; - -        /* We need to invalidate because it is possible that write-behind -         * is a translator below us and returns a stat filled with zeroes. -         */ -        libgf_invalidate_iattr_cache (fd->inode, LIBGF_INVALIDATE_STAT); - -out: -        if (iob) { -                iobuf_unref (iob); -        } - -        if (ioref) { -                iobref_unref (ioref); -        } - -        call_stub_destroy (stub); -        return op_ret; -} - -int -libgf_client_writev (libglusterfs_client_ctx_t *ctx,  -                     fd_t *fd,  -                     struct iovec *vector,  -                     int count,  -                     off_t offset) -{ -        int                     op_ret = 0; -        int                     written = 0; -        int                     writesize = 0; -        int                     size = 0; -        char                   *base = NULL; -        int                     i = 0; - -        for (i = 0; i < count; i++) { -                size = vector[i].iov_len; -                base = vector[i].iov_base; - -                while (size > 0) { -                        writesize = (size > LIBGF_IOBUF_SIZE) ? -                                LIBGF_IOBUF_SIZE : size; - -                        written = libgf_client_iobuf_write (ctx, fd, base, -                                                            writesize, offset); - -                        if (written == -1) -                                goto out; - -                        op_ret += written; -                        base += written; -                        size -= written; -                        offset += written; -                } -        } - -out: -        return op_ret; -} - - -ssize_t  -glusterfs_write (glusterfs_file_t fd,  -                 const void *buf,  -                 size_t n) -{ -        int32_t op_ret = -1; -        off_t offset = 0; -        struct iovec vector; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        if (n < 0) { -                errno = EINVAL; -                goto out; -        } - -        if (n == 0) { -                op_ret = 0; -                goto out; -        } - -        if (!fd) { -                errno = EINVAL; -		goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        ctx = fd_ctx->ctx; - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                offset = fd_ctx->offset; -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -        vector.iov_base = (void *)buf; -        vector.iov_len = n; - -        op_ret = libgf_client_writev (ctx, -                                      (fd_t *)fd,  -                                      &vector,  -                                      1,  -                                      offset); - -        if (op_ret >= 0) { -                offset += op_ret; -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        fd_ctx->offset = offset; -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -out: -        return op_ret; -} - -ssize_t  -glusterfs_writev (glusterfs_file_t fd,  -                  const struct iovec *vector, -                  int count) -{ -        int32_t op_ret = -1; -        off_t offset = 0; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        if (count < 0) { -                errno = EINVAL; -                goto out; -        } - -        if (count == 0) { -                op_ret = 0; -                goto out; -        } - -        if (!fd) { -                errno = EINVAL; -		goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        ctx = fd_ctx->ctx; - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                offset = fd_ctx->offset; -        } -        pthread_mutex_unlock (&fd_ctx->lock); - - -        op_ret = libgf_client_writev (ctx, -                                      (fd_t *)fd,  -                                      (struct iovec *)vector,  -                                      count, -                                      offset); - -        if (op_ret >= 0) { -                offset += op_ret; -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        fd_ctx->offset = offset; -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -out: -        return op_ret; -} - - -ssize_t  -glusterfs_pwrite (glusterfs_file_t fd,  -                  const void *buf,  -                  size_t count,  -                  off_t offset) -{ -        int32_t op_ret = -1; -        struct iovec vector; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        if (count < 0) { -                errno = EINVAL; -                goto out; -        } - -        if (count == 0) { -                op_ret = 0; -                goto out; -        } - -        if (!fd) { -                errno = EINVAL; -		goto out; -        } - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        ctx = fd_ctx->ctx; - -        vector.iov_base = (void *)buf; -        vector.iov_len = count; - -        op_ret = libgf_client_writev (ctx, -                                      (fd_t *)fd,  -                                      &vector,  -                                      1,  -                                      offset); - -out: -        return op_ret; -} - - -int32_t -libgf_client_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                           int32_t op_ret, int32_t op_errno, -                           gf_dirent_t *entries) -{ -        libgf_client_local_t *local = frame->local; - -        /* Note, we dont let entries reach the stub because there it gets copied -         * while we can simply delink the entries here and link them into our -         * dcache, thereby avoiding the need to perform more allocations and -         * copies. -         */ -        local->reply_stub = fop_readdirp_cbk_stub (frame, NULL, op_ret, -                                                   op_errno, NULL); -        if (op_ret > 0) -                libgf_dcache_update (frame->root->state, local->fd, entries); -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int  -libgf_client_readdir (libglusterfs_client_ctx_t *ctx, fd_t *fd, -                      struct dirent *dirp, off_t *offset) -{   -        call_stub_t *stub = NULL; -        int op_ret = -1; -        libgf_client_local_t *local = NULL; - -        if (libgf_dcache_readdir (ctx, fd, dirp, offset)) -                return 1; -        local = CALLOC (1, sizeof (*local)); -        ERR_ABORT (local); -        local->fd = fd; -        LIBGF_CLIENT_FOP (ctx, stub, readdirp, local, fd, -                          LIBGF_READDIR_BLOCK, *offset); - -        errno = stub->args.readdir_cbk.op_errno; - -        op_ret = libgf_dcache_readdir (ctx, fd, dirp, offset); -	call_stub_destroy (stub); -        return op_ret; -} - - -int -glusterfs_readdir_r (glusterfs_dir_t dirfd, struct dirent *entry, -                     struct dirent **result) -{ -        int                           op_ret = -1; -        libglusterfs_client_ctx_t    *ctx = NULL; -        off_t                         offset = 0; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -        struct dirent                *dirp = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, entry, out); - -        fd_ctx = libgf_get_fd_ctx (dirfd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "fd context not present"); -                errno = EBADF; -		goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                ctx = fd_ctx->ctx; -                offset = fd_ctx->offset; -                dirp = &fd_ctx->dirp; - -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "offset %"PRIu64, offset); -                memset (dirp, 0, sizeof (struct dirent)); -                op_ret = libgf_client_readdir (ctx, (fd_t *)dirfd, dirp, -                                               &offset); -                if (op_ret <= 0) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "readdir failed:" -                                " %s", strerror (errno)); -                        if (result && (op_ret == 0)) { -                                *result = NULL; -                        } else if (op_ret < 0){ -                                op_ret = errno; -                        } -                        goto unlock; -                } - -                fd_ctx->offset = offset; - -                if (result) { -                        *result = memcpy (entry, dirp, sizeof (*entry)); -                } else { -                        memcpy (entry, dirp, sizeof (*entry)); -                } - -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "new offset %"PRIu64", " -                        " entry %s", offset, entry->d_name); -                op_ret = 0; -        } -unlock: -        pthread_mutex_unlock (&fd_ctx->lock); - -out: -        return op_ret; -} - - -void * -glusterfs_readdir (glusterfs_dir_t dirfd) -{ -        int op_ret = -1; -        libglusterfs_client_ctx_t *ctx = NULL; -        off_t offset = 0; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -        struct dirent *dirp = NULL; - -        fd_ctx = libgf_get_fd_ctx (dirfd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "fd context not present"); -                errno = EBADF; -		goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                ctx = fd_ctx->ctx; -                offset = fd_ctx->offset; -                dirp = &fd_ctx->dirp; -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "offset %"PRIu64, offset); -        memset (dirp, 0, sizeof (struct dirent)); -        op_ret = libgf_client_readdir (ctx, (fd_t *)dirfd, dirp, &offset); - -        if (op_ret <= 0) { -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "readdir failed: %s", -                        strerror (errno)); -                dirp = NULL; -                goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                fd_ctx->offset = offset; -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "new offset %"PRIu64", entry %s", -                offset, dirp->d_name); -out: -        return dirp; -} - - -int -glusterfs_getdents (glusterfs_file_t fd, struct dirent *dirp, -                    unsigned int count) -{ -        int op_ret = -1; -        libglusterfs_client_ctx_t *ctx = NULL; -        off_t offset = 0; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                ctx = fd_ctx->ctx; -                offset = fd_ctx->offset; -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -        op_ret = libgf_client_readdir (ctx, (fd_t *)fd, dirp, &offset); - -        if (op_ret > 0) { -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        fd_ctx->offset = offset; -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -out: -        return op_ret; -} - - -static int32_t -libglusterfs_readv_async_cbk (call_frame_t *frame, -                              void *cookie, -                              xlator_t *this, -                              int32_t op_ret, -                              int32_t op_errno, -                              struct iovec *vector, -                              int32_t count, -                              struct iatt *stbuf, -                              struct iobref *iobref) -{ -        glusterfs_iobuf_t *buf; -        libglusterfs_client_async_local_t *local = frame->local; -        fd_t *__fd = local->fop.readv_cbk.fd; -        glusterfs_readv_cbk_t readv_cbk = local->fop.readv_cbk.cbk; - -        buf = CALLOC (1, sizeof (*buf)); -        ERR_ABORT (buf); - -	if (vector) { -		buf->vector = iov_dup (vector, count); -	} - -        buf->count = count; - -	if (iobref) { -		buf->iobref = iobref_ref (iobref); -	} - -        if (op_ret > 0) { -                libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -                fd_ctx = libgf_get_fd_ctx (__fd); -                 -                /* update offset only if we have used offset stored in fd_ctx */ -                if (local->fop.readv_cbk.update_offset) { -                        pthread_mutex_lock (&fd_ctx->lock); -                        { -                                fd_ctx->offset += op_ret; -                        } -                        pthread_mutex_unlock (&fd_ctx->lock); -                } -        } - -        readv_cbk (op_ret, op_errno, buf, local->cbk_data);  - -	FREE (local); -	frame->local = NULL; -        STACK_DESTROY (frame->root); - -        return 0; -} - -void  -glusterfs_free (glusterfs_iobuf_t *buf) -{ -        //iov_free (buf->vector, buf->count); -        FREE (buf->vector); -        if (buf->iobref) -                iobref_unref ((struct iobref *) buf->iobref); -        if (buf->dictref) -                dict_unref ((dict_t *) buf->dictref); -        FREE (buf); -} - -int -glusterfs_read_async (glusterfs_file_t fd,  -                      size_t nbytes,  -                      off_t offset, -                      glusterfs_readv_cbk_t readv_cbk, -                      void *cbk_data) -{ -        libglusterfs_client_ctx_t *ctx; -        fd_t *__fd = (fd_t *)fd; -        libglusterfs_client_async_local_t *local = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -	int32_t op_ret = 0; - -        if (nbytes < 0) { -                errno = EINVAL; -                op_ret = -1; -                goto out; -        } - -        if (nbytes == 0) { -                op_ret = 0; -                goto out; -        } - -        local = CALLOC (1, sizeof (*local)); -        ERR_ABORT (local); -        local->fop.readv_cbk.fd = __fd; -        local->fop.readv_cbk.cbk = readv_cbk; -        local->cbk_data = cbk_data; - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		op_ret = -1; -		goto out; -        } - -        ctx = fd_ctx->ctx; - -        if (offset < 0) { -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        offset = fd_ctx->offset; -                        local->fop.readv_cbk.update_offset = 1; -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -        LIBGF_CLIENT_FOP_ASYNC (ctx, -                                local, -                                libglusterfs_readv_async_cbk, -                                readv, -                                __fd, -                                nbytes, -                                offset); - -out: -        return op_ret; -} - -static int32_t -libglusterfs_writev_async_cbk (call_frame_t *frame, -                               void *cookie, -                               xlator_t *this, -                               int32_t op_ret, -                               int32_t op_errno, -                               struct iatt *prebuf, -                               struct iatt *postbuf) -{ -        libglusterfs_client_async_local_t *local = frame->local; -        fd_t *fd = NULL; -        glusterfs_write_cbk_t write_cbk; - -        write_cbk = local->fop.write_cbk.cbk; -        fd = local->fop.write_cbk.fd; - -        if (op_ret > 0) { -                libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -                fd_ctx = libgf_get_fd_ctx (fd); -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        fd_ctx->offset += op_ret;   -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -        write_cbk (op_ret, op_errno, local->cbk_data); - -        STACK_DESTROY (frame->root); -        return 0; -} - -int32_t -glusterfs_write_async (glusterfs_file_t fd,  -                       const void *buf,  -                       size_t nbytes,  -                       off_t offset, -                       glusterfs_write_cbk_t write_cbk, -                       void *cbk_data) -{ -        fd_t *__fd = (fd_t *)fd; -        struct iovec vector; -        off_t __offset = offset; -        libglusterfs_client_ctx_t *ctx = NULL; -        libglusterfs_client_async_local_t *local = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -	int32_t op_ret = 0; -        struct iobref *iobref = NULL; - -        if (nbytes == 0) { -                op_ret = 0; -                goto out; -        } - -        if (nbytes < 0) { -                op_ret = -1; -                errno = EINVAL; -                goto out; -        } - -        local = CALLOC (1, sizeof (*local)); -        ERR_ABORT (local); -        local->fop.write_cbk.fd = __fd; -        local->fop.write_cbk.cbk = write_cbk; -        local->cbk_data = cbk_data; - -        vector.iov_base = (void *)buf; -        vector.iov_len = nbytes; -   -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		op_ret = -1; -		goto out; -        } - -        ctx = fd_ctx->ctx; -  -        if (offset < 0) { -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        __offset = fd_ctx->offset; -                } -                pthread_mutex_unlock (&fd_ctx->lock); -        } - -        iobref = iobref_new (); -        LIBGF_CLIENT_FOP_ASYNC (ctx, -                                local, -                                libglusterfs_writev_async_cbk, -                                writev, -                                __fd, -                                &vector, -                                1, -                                __offset, -                                iobref); -        iobref_unref (iobref); - -out: -        return op_ret; -} - -off_t -glusterfs_lseek (glusterfs_file_t fd, off_t offset, int whence) -{ -        off_t __offset = 0; -	int32_t op_ret = -1; -        fd_t *__fd = (fd_t *)fd; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -	libglusterfs_client_ctx_t *ctx = NULL;  - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		__offset = -1; -		goto out; -        } - -	ctx = fd_ctx->ctx; - -        switch (whence) -        { -        case SEEK_SET: -                __offset = offset; -                break; - -        case SEEK_CUR: -                pthread_mutex_lock (&fd_ctx->lock); -                { -                        __offset = fd_ctx->offset; -                } -                pthread_mutex_unlock (&fd_ctx->lock); - -                __offset += offset; -                break; - -        case SEEK_END: -	{ -		char cache_valid = 0; -		off_t end = 0; -		loc_t loc = {0, }; -		struct iatt stbuf = {0, }; - -                cache_valid = libgf_is_iattr_cache_valid (ctx, __fd->inode, -                                                          &stbuf, -                                                          LIBGF_VALIDATE_STAT); -                if (cache_valid) { -			end = stbuf.ia_size; -		} else { -			op_ret = libgf_client_loc_fill (&loc, ctx, -                                                        __fd->inode->ino, 0, -                                                        NULL); -			if (op_ret == -1) { -				gf_log ("libglusterfsclient", -					GF_LOG_ERROR, -					"libgf_client_loc_fill returned -1, returning EINVAL"); -				errno = EINVAL; -				libgf_client_loc_wipe (&loc); -				__offset = -1; -				goto out; -			} -			 -			op_ret = libgf_client_lookup (ctx, &loc, &stbuf, NULL, -                                                      NULL); -			if (op_ret < 0) { -				__offset = -1; -				libgf_client_loc_wipe (&loc); -				goto out; -			} - -			end = stbuf.ia_size; -		} - -                __offset = end + offset;  -		libgf_client_loc_wipe (&loc); -	} -	break; - -	default: -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"invalid value for whence"); -		__offset = -1; -		errno = EINVAL; -		goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                fd_ctx->offset = __offset; -        } -        pthread_mutex_unlock (&fd_ctx->lock); -  -out:  -        return __offset; -} - - -int32_t -libgf_client_stat_cbk (call_frame_t *frame, -                       void *cookie, -                       xlator_t *this, -                       int32_t op_ret, -                       int32_t op_errno, -                       struct iatt *buf) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_stat_cbk_stub (frame,  -                                               NULL,  -                                               op_ret,  -                                               op_errno,  -                                               buf); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int32_t  -libgf_client_stat (libglusterfs_client_ctx_t *ctx,  -                   loc_t *loc, -                   struct iatt *stbuf) -{ -        call_stub_t *stub = NULL; -        int32_t op_ret = 0; -        libgf_client_local_t *local = NULL; -        struct iatt cachedbuf = {0, }; - -        if (libgf_is_iattr_cache_valid (ctx, loc->inode, &cachedbuf, -                                        LIBGF_VALIDATE_STAT)) { -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Cache will be used"); -                if (stbuf) -                        memcpy (stbuf, &cachedbuf, sizeof (struct stat)); -                goto out; -        } - -        LIBGF_CLIENT_FOP (ctx, stub, stat, local, loc); -  -        op_ret = stub->args.stat_cbk.op_ret; -        errno = stub->args.stat_cbk.op_errno; -        libgf_transform_iattr (ctx, loc->inode, &stub->args.stat_cbk.buf); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, status %d, errno %d", -                loc->path, op_ret, errno); - -        if (op_ret == 0) { -                if (stbuf) -                        *stbuf = stub->args.stat_cbk.buf; - -                libgf_update_iattr_cache (loc->inode, LIBGF_UPDATE_STAT, -                                          &stub->args.stat_cbk.buf); -        } - -	call_stub_destroy (stub); - -out: -        return op_ret; -} - -int -libgf_realpath_loc_fill (libglusterfs_client_ctx_t *ctx, char *link, -                                loc_t *targetloc) -{ -        int             op_ret = -1; -        char            *target = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, link, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, targetloc, out); - -        targetloc->path = glusterfs_glh_realpath (ctx, link, NULL); - -        if (targetloc->path == NULL) -                goto out; - -        op_ret = libgf_client_path_lookup (targetloc, ctx, 1); -        if (op_ret == -1) -                goto out; - -        target = strdup (targetloc->path); -        op_ret = libgf_client_loc_fill (targetloc, ctx, 0, -                                               targetloc->parent->ino, -                                               basename (target)); -        if (op_ret == -1) { -                errno = EINVAL; -                goto out; -        } - -out: -        if (target) -                FREE (target); - -        return op_ret; -} - -#define LIBGF_DO_LSTAT  0x01 -#define LIBGF_DO_STAT   0x02 - -int -__glusterfs_stat (glusterfs_handle_t handle, const char *path, -                  struct stat *buf, int whichstat) -{ -        int32_t op_ret = -1; -        loc_t loc = {0, }; -        libglusterfs_client_ctx_t *ctx = handle; -	char *name = NULL, *pathname = NULL; -        loc_t targetloc = {0, }; -        loc_t *real_loc = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, op: %d", path, -                whichstat); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -	op_ret = libgf_client_path_lookup (&loc, ctx, 1); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", GF_LOG_ERROR, -			"path lookup failed for (%s)", loc.path); -		goto out; -	} - -	pathname = strdup (loc.path); -	name = basename (pathname); - -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} -        real_loc = &loc; -        /* The stat fop in glusterfs calls lstat. So we have to -         * provide the POSIX compatible stat fop. To do so, we need to ensure -         * that if the @path is a symlink, we must perform a stat on the -         * target of that symlink than the symlink itself(..because if -         * do a stat on the symlink, we're actually doing what lstat -         * should do. See posix_stat -         */ -        if (whichstat & LIBGF_DO_LSTAT) -                goto lstat_fop; - -        if (!IA_ISLNK (loc.inode->ia_type)) -                goto lstat_fop; - -        op_ret = libgf_realpath_loc_fill (ctx, (char *)loc.path, &targetloc); -        if (op_ret == -1) -                goto out; -        real_loc = &targetloc; - -lstat_fop: - -        if (!op_ret) { -                struct iatt iatt; -                op_ret = libgf_client_stat (ctx, real_loc, &iatt); -                iatt_to_stat (&iatt, buf); -        } - -out: -	if (pathname) { -		FREE (pathname); -	} - -        libgf_client_loc_wipe (&loc); -        libgf_client_loc_wipe (&targetloc); - -        return op_ret; -} - -int -glusterfs_glh_stat (glusterfs_handle_t handle, const char *path, -                    struct stat *buf) -{ -        return __glusterfs_stat (handle, path, buf, LIBGF_DO_STAT); -} - -int -glusterfs_stat (const char *path, struct stat *buf) -{ -        glusterfs_handle_t      h      = NULL; -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, buf, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_stat (h, vpath, buf); - -out: -        return op_ret; -} - -int -glusterfs_glh_lstat (glusterfs_handle_t handle, const char *path, struct stat *buf) -{ -        return __glusterfs_stat (handle, path, buf, LIBGF_DO_LSTAT); -} - -int -glusterfs_lstat (const char *path, struct stat *buf) -{ -        glusterfs_handle_t      h      = NULL; -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, buf, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_lstat (h, vpath, buf); -out: -        return op_ret; -} - -static int32_t -libgf_client_fstat_cbk (call_frame_t *frame, -                        void *cookie, -                        xlator_t *this, -                        int32_t op_ret, -                        int32_t op_errno, -                        struct iatt *buf) -{   -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_fstat_cbk_stub (frame,  -                                                NULL,  -                                                op_ret,  -                                                op_errno,  -                                                buf); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; - -} - -int32_t -libgf_client_fstat (libglusterfs_client_ctx_t *ctx,  -                    fd_t *fd,  -                    struct stat *buf) -{ -        call_stub_t *stub = NULL; -        int32_t op_ret = 0; -        libgf_client_local_t *local = NULL; -        struct iatt cachedbuf = {0, }; - -        if (libgf_is_iattr_cache_valid (ctx, fd->inode, &cachedbuf, -                                        LIBGF_VALIDATE_STAT)) { -                if (buf) -                        memcpy (buf, &cachedbuf, sizeof (struct stat)); -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Cache will be used"); -                goto out; -        } - -        LIBGF_CLIENT_FOP (ctx, stub, fstat, local, fd); -  -        op_ret = stub->args.fstat_cbk.op_ret; -        errno = stub->args.fstat_cbk.op_errno; -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "status %d, errno %d", op_ret, -                errno); - -        if (op_ret == 0) { -                libgf_transform_iattr (ctx, fd->inode, -                                       &stub->args.fstat_cbk.buf); -                if (buf) -                        iatt_to_stat (&stub->args.fstat_cbk.buf, buf); -                libgf_update_iattr_cache (fd->inode, LIBGF_UPDATE_STAT, -                                          &stub->args.fstat_cbk.buf); -        } -	call_stub_destroy (stub); - -out: -        return op_ret; -} - -int32_t  -glusterfs_fstat (glusterfs_file_t fd, struct stat *buf)  -{ -        libglusterfs_client_ctx_t *ctx; -        fd_t *__fd = (fd_t *)fd; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -	int32_t op_ret = -1; - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -		op_ret = -1; -		goto out; -        } - -        ctx = fd_ctx->ctx; - -	op_ret = libgf_client_fstat (ctx, __fd, buf); - -out: -	return op_ret; -} - - -static int32_t -libgf_client_mkdir_cbk (call_frame_t *frame, -			void *cookie, -			xlator_t *this, -			int32_t op_ret, -			int32_t op_errno, -			inode_t *inode, -                        struct iatt *buf, -                        struct iatt *preparent, -                        struct iatt *postparent) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_mkdir_cbk_stub (frame, NULL, op_ret, op_errno, -                                                inode, buf, preparent, -                                                postparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - - -static int32_t -libgf_client_mkdir (libglusterfs_client_ctx_t *ctx, -		    loc_t *loc, -		    mode_t mode) -{ -	int32_t op_ret = -1; -        call_stub_t *stub = NULL; -        libgf_client_local_t *local = NULL; -        inode_t *libgf_inode = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, mkdir, local, loc, mode); -        op_ret = stub->args.mkdir_cbk.op_ret; -        errno = stub->args.mkdir_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, status %d, errno %d", -                loc->path, op_ret, errno); -        if (op_ret == -1) -                goto out; - -	libgf_inode = stub->args.mkdir_cbk.inode; -        inode_link (libgf_inode, loc->parent, loc->name, -                        &stub->args.mkdir_cbk.buf); -        libgf_transform_iattr (ctx, libgf_inode, &stub->args.mkdir_cbk.buf); - -        inode_lookup (libgf_inode); - -        libgf_alloc_inode_ctx (ctx, libgf_inode); -        libgf_update_iattr_cache (libgf_inode, LIBGF_UPDATE_ALL, -                                        &stub->args.mkdir_cbk.buf); - -out: -	call_stub_destroy (stub); - -	return op_ret; -} - - -int32_t -glusterfs_glh_mkdir (glusterfs_handle_t handle, const char *path, mode_t mode) -{ -	libglusterfs_client_ctx_t *ctx = handle; -	loc_t loc = {0, }; -	char *pathname = NULL, *name = NULL; -	int32_t op_ret = -1; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -	op_ret = libgf_client_path_lookup (&loc, ctx, 1); -	if (op_ret == 0) { -                op_ret = -1; -                errno = EEXIST; -		goto out; -	} - -        op_ret = libgf_client_path_lookup (&loc, ctx, 0); -        if (op_ret == -1) { -                errno = ENOENT; -                goto out; -        } - -	pathname = strdup (loc.path); -	name = basename (pathname); - -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} - -        loc.inode = inode_new (ctx->itable); -	op_ret = libgf_client_mkdir (ctx, &loc, mode);  -	if (op_ret == -1) { -		goto out; -	} - -out: -	libgf_client_loc_wipe (&loc); -	if (pathname) { -		free (pathname); -		pathname = NULL; -	} - -	return op_ret; -} - -int32_t -glusterfs_mkdir (const char *path, mode_t mode) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_mkdir (h, vpath, mode); -out: -        return op_ret; -} - -static int32_t -libgf_client_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno,struct iatt *preparent, -                        struct iatt *postparent) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_rmdir_cbk_stub (frame, NULL, op_ret, op_errno, -                                                preparent, postparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -static int32_t -libgf_client_rmdir (libglusterfs_client_ctx_t *ctx, loc_t *loc) -{ -        int32_t op_ret = -1; -        call_stub_t *stub = NULL; -        libgf_client_local_t *local = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, rmdir, local, loc); - -        op_ret = stub->args.rmdir_cbk.op_ret; -        errno = stub->args.rmdir_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, status %d, errno %d", -                loc->path, op_ret, errno); -        if (stub->args.rmdir_cbk.op_ret != 0) -                goto out; - -        inode_unlink (loc->inode, loc->parent, loc->name); - -out: -	call_stub_destroy (stub); - -	return op_ret; -} - -int32_t -glusterfs_glh_rmdir (glusterfs_handle_t handle, const char *path) -{ -	libglusterfs_client_ctx_t *ctx = handle; -	loc_t loc = {0, }; -	char *pathname = NULL, *name = NULL; -	int32_t op_ret = -1; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        loc.path = libgf_resolve_path_light ((char *)path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Path compaction failed"); -                goto out; -        } - -	op_ret = libgf_client_path_lookup (&loc, ctx, 1); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", GF_LOG_ERROR, -			"path lookup failed for (%s)", loc.path); -		goto out; -	} - -	pathname = strdup (loc.path); -	name = basename (pathname); - -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} - -	op_ret = libgf_client_rmdir (ctx, &loc); -	if (op_ret == -1) { -		goto out; -	} - -out: -	libgf_client_loc_wipe (&loc); - -	if (pathname) { -		free (pathname); -		pathname = NULL; -	} - -	return op_ret; -} - -int32_t -glusterfs_rmdir (const char *path) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_rmdir (h, vpath); -out: -        return op_ret; -} - -int -libgf_client_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                          int32_t op_ret, int32_t op_errno, -                          struct iatt *preop, struct iatt *postop) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_setattr_cbk_stub (frame, NULL, -                                                  op_ret, op_errno, -                                                  preop, postop); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int -libgf_client_setattr (libglusterfs_client_ctx_t *ctx, loc_t * loc, -                      struct iatt *stbuf, int32_t valid) -{ -        int                             op_ret = -1; -        libgf_client_local_t            *local = NULL; -        call_stub_t                     *stub = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, setattr, local, loc, -                          stbuf, valid); - -        op_ret = stub->args.setattr_cbk.op_ret; -        errno = stub->args.setattr_cbk.op_errno; - -        if (op_ret == -1) -                goto out; - -        libgf_transform_iattr (ctx, loc->inode, -                               &stub->args.setattr_cbk.statpost); -        libgf_update_iattr_cache (loc->inode, LIBGF_UPDATE_STAT, -                                  &stub->args.setattr_cbk.statpost); -out: -        call_stub_destroy (stub); -        return op_ret; -} - - -int -glusterfs_glh_chmod (glusterfs_handle_t handle, const char *path, mode_t mode) -{ -        int                             op_ret = -1; -        libglusterfs_client_ctx_t       *ctx = handle; -        loc_t                           loc = {0, }; -        char                            *name = NULL; -        struct iatt                     stbuf = {0,}; -        int32_t                         valid = 0; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        stbuf.ia_prot = ia_prot_from_st_mode (mode); -        valid |= GF_SET_ATTR_MODE; - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) -                goto out; - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -        if (op_ret == -1) { -                errno = EINVAL; -                goto out; -        } - -        op_ret = libgf_client_setattr (ctx, &loc, &stbuf, valid); - -out: -        if (name) -                FREE (name); - -        libgf_client_loc_wipe (&loc); -        return op_ret; -} - -int -glusterfs_chmod (const char *path, mode_t mode) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_chmod (h, vpath, mode); -out: -        return op_ret; -} - - -#define LIBGF_DO_CHOWN  1 -#define LIBGF_DO_LCHOWN 2 - -int -__glusterfs_chown (glusterfs_handle_t handle, const char *path, uid_t owner, -                   gid_t group, int whichop) -{ -        int                             op_ret = -1; -        libglusterfs_client_ctx_t       *ctx = handle; -        loc_t                           loc = {0, }; -        char                            *name = NULL; -        loc_t                           *oploc = NULL; -        loc_t                           targetloc = {0, }; -        struct iatt                     stbuf = {0,}; -        int32_t                         valid = 0; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, op %d", path, whichop); -        stbuf.ia_uid = owner; -        stbuf.ia_gid = group; -        valid |= (GF_SET_ATTR_UID | GF_SET_ATTR_GID); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) -                goto out; - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                        basename ((char *)name)); -        if (op_ret == -1) { -                errno = EINVAL; -                goto out; -        } - -        oploc = &loc; -        if (whichop == LIBGF_DO_LCHOWN) -                goto do_lchown; - -        if (!IA_ISLNK (loc.inode->ia_type)) -                goto do_lchown; - -        op_ret = libgf_realpath_loc_fill (ctx, (char *)loc.path, &targetloc); -        if (op_ret == -1) -                goto out; - -        oploc = &targetloc; -do_lchown: -        op_ret = libgf_client_setattr (ctx, oploc, &stbuf, valid); -out: -        if (name) -                FREE (name); -        libgf_client_loc_wipe (&loc); -        libgf_client_loc_wipe (&targetloc); -        return op_ret; -} - -int -glusterfs_glh_chown (glusterfs_handle_t handle, const char *path, uid_t owner, -                     gid_t group) -{ -        return __glusterfs_chown (handle, path, owner, group, LIBGF_DO_CHOWN); -} - -int -glusterfs_chown (const char *path, uid_t owner, gid_t group) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_chown (h, vpath, owner, group); - -out: -        return op_ret; -} - -int -glusterfs_glh_lchown (glusterfs_handle_t handle, const char *path, uid_t owner, -                     gid_t group) -{ -        return __glusterfs_chown (handle, path, owner, group, LIBGF_DO_LCHOWN); -} - -int -glusterfs_lchown (const char *path, uid_t owner, gid_t group) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_lchown (h, vpath, owner, group); -out: -        return op_ret; -} - -glusterfs_dir_t -glusterfs_glh_opendir (glusterfs_handle_t handle, const char *path) -{ -        int                             op_ret = -1; -        libglusterfs_client_ctx_t       *ctx = handle; -        loc_t                           loc = {0, }; -        fd_t                            *dirfd = NULL; -        char                            *name = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); - -        if (op_ret == -1) -                goto out; - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                        basename (name)); -        if (op_ret == -1) { -                errno = EINVAL; -                goto out; -        } - -        if (!IA_ISDIR (loc.inode->ia_type) && !IA_ISLNK (loc.inode->ia_type)) { -                errno = ENOTDIR; -                op_ret = -1; -                goto out; -        } - -        dirfd = fd_create (loc.inode, ctx->pid); -        op_ret = libgf_client_opendir (ctx, &loc, dirfd); - -        if (op_ret == -1) { -                fd_unref (dirfd); -                dirfd = NULL; -                goto out; -        } - -        if (!libgf_get_fd_ctx (dirfd)) { -                if (!(libgf_alloc_fd_ctx (ctx, dirfd, (char *)path))) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Context " -                                "allocation failed"); -                        op_ret = -1; -                        errno = EINVAL; -                        goto out; -                } -        } - -out: -        if (name) -                FREE (name); - -        if (op_ret == -1) { -                fd_unref (dirfd); -                dirfd = NULL; -        } - -        libgf_client_loc_wipe (&loc); -        return dirfd; -} - -glusterfs_dir_t -glusterfs_opendir (const char *path) -{ -        char                    vpath[PATH_MAX]; -        glusterfs_dir_t         dir = NULL; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        dir = glusterfs_glh_opendir (h, vpath); -out: -        return dir; -} - -int -glusterfs_closedir (glusterfs_dir_t dirfd) -{ -        int                             op_ret = -1; -        libglusterfs_client_fd_ctx_t    *fdctx = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, dirfd, out); -        fdctx = libgf_get_fd_ctx (dirfd); - -        if (fdctx == NULL) { -                errno = EBADF; -                op_ret = -1; -                goto out; -        } - -        op_ret = libgf_client_flush (fdctx->ctx, (fd_t *)dirfd); -        fd_unref ((fd_t *)dirfd); - -out: -        return op_ret; -} - - -int -libgf_client_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                           int32_t op_ret, int32_t op_errno, -                           struct iatt *preop, struct iatt *postop) -{ -        libgf_client_local_t    *local = frame->local; - -        local->reply_stub = fop_fsetattr_cbk_stub (frame, NULL, -                                                   op_ret, op_errno, -                                                   preop, postop); -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - - -int -libgf_client_fsetattr (libglusterfs_client_ctx_t *ctx, fd_t *fd, -                       struct iatt *stbuf, int32_t valid) -{ -        int                     op_ret = -1; -        libgf_client_local_t    *local = NULL; -        call_stub_t             *stub = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, fsetattr, local, fd, stbuf, valid); - -        op_ret = stub->args.fsetattr_cbk.op_ret; -        errno = stub->args.fsetattr_cbk.op_errno; - -        if (op_ret == -1) -                goto out; - -        libgf_transform_iattr (ctx, fd->inode, -                               &stub->args.fsetattr_cbk.statpost); -        libgf_update_iattr_cache (fd->inode, LIBGF_UPDATE_STAT, -                                  &stub->args.fsetattr_cbk.statpost); -out: -        call_stub_destroy (stub); -        return op_ret; -} - - -int -glusterfs_fchmod (glusterfs_file_t fd, mode_t mode) -{ -        libglusterfs_client_fd_ctx_t    *fdctx = NULL; -        int                             op_ret = -1; -        struct iatt                     stbuf = {0,}; -        int32_t                         valid = 0; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); -        fdctx = libgf_get_fd_ctx (fd); - -        if (!fdctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "No fd context present"); -                errno = EBADF; -                goto out; -        } - -        stbuf.ia_prot = ia_prot_from_st_mode (mode); -        valid |= GF_SET_ATTR_MODE; - -        op_ret = libgf_client_fsetattr (fdctx->ctx, fd, &stbuf, valid); -out: -        return op_ret; -} - - -int -glusterfs_fchown (glusterfs_file_t fd, uid_t uid, gid_t gid) -{ -        int                             op_ret = -1; -        libglusterfs_client_fd_ctx_t    *fdctx = NULL; -        struct iatt                     stbuf = {0,}; -        int32_t                         valid = 0; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); - -        fdctx = libgf_get_fd_ctx (fd); -        if (!fd) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                goto out; -        } -        stbuf.ia_uid = uid; -        stbuf.ia_gid = gid; - -        valid |= (GF_SET_ATTR_UID | GF_SET_ATTR_GID); - -        op_ret = libgf_client_fsetattr (fdctx->ctx, fd, &stbuf, valid); - -out: -        return op_ret; -} - -int -libgf_client_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *xlator, -                        int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                        struct iatt *postbuf) -{ -        libgf_client_local_t    *local = frame->local; - -        local->reply_stub = fop_fsync_cbk_stub (frame, NULL, op_ret, op_errno, -                                                prebuf, postbuf); - -        LIBGF_REPLY_NOTIFY (local); - -        return 0; -} - -int -libgf_client_fsync (libglusterfs_client_ctx_t *ctx, fd_t *fd) -{ -        libgf_client_local_t    *local = NULL; -        call_stub_t             *stub = NULL; -        int                     op_ret = -1; - -        LIBGF_CLIENT_FOP (ctx, stub, fsync, local, fd, 0); - -        op_ret = stub->args.fsync_cbk.op_ret; -        errno = stub->args.fsync_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "status %d, errno %d", op_ret, -                errno); -        call_stub_destroy (stub); - -        return op_ret; -} - -int -glusterfs_fsync (glusterfs_file_t *fd) -{ -        libglusterfs_client_fd_ctx_t    *fdctx = NULL; -        int                             op_ret = -1; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); - -        fdctx = libgf_get_fd_ctx ((fd_t *)fd); -        if (!fdctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                goto out; -        } - -        op_ret = libgf_client_fsync (fdctx->ctx, (fd_t *)fd); - -out: -        return op_ret; -} - -int -libgf_client_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *xlator -                                ,int32_t op_ret, int32_t op_errno, -                                struct iatt *prebuf, struct iatt *postbuf) -{ -        libgf_client_local_t    *local = frame->local; - -        local->reply_stub = fop_ftruncate_cbk_stub (frame, NULL, op_ret, -                                                    op_errno, prebuf, postbuf); - -        LIBGF_REPLY_NOTIFY (local); - -        return 0; -} - -int -libgf_client_ftruncate (libglusterfs_client_ctx_t *ctx, fd_t *fd, -                                off_t length) -{ -        libgf_client_local_t            *local = NULL; -        call_stub_t                     *stub = NULL; -        int                             op_ret = -1; -        libglusterfs_client_fd_ctx_t    *fdctx = NULL; - -        if (!(((fd->flags & O_ACCMODE) == O_RDWR) -              || ((fd->flags & O_ACCMODE) == O_WRONLY))) { -                errno = EBADF; -                goto out; -        } - -        LIBGF_CLIENT_FOP (ctx, stub, ftruncate, local, fd, length); - -        op_ret = stub->args.ftruncate_cbk.op_ret; -        errno = stub->args.ftruncate_cbk.op_errno; - -        if (op_ret == -1) -                goto out; - -        libgf_transform_iattr (ctx, fd->inode, -                               &stub->args.ftruncate_cbk.postbuf); -        libgf_update_iattr_cache (fd->inode, LIBGF_UPDATE_STAT, -                                        &stub->args.ftruncate_cbk.postbuf); - -        fdctx = libgf_get_fd_ctx (fd); -        if (!fd) { -                errno = EINVAL; -                op_ret = -1; -                goto out; -        } - -        pthread_mutex_lock (&fdctx->lock); -        { -                fdctx->offset = stub->args.ftruncate_cbk.postbuf.ia_size; -        } -        pthread_mutex_unlock (&fdctx->lock); - -out: -        call_stub_destroy (stub); -        return op_ret; -} - -int -glusterfs_ftruncate (glusterfs_file_t fd, off_t length) -{ -        libglusterfs_client_fd_ctx_t    *fdctx = NULL; -        int                             op_ret = -1; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); - -        fdctx = libgf_get_fd_ctx (fd); -        if (!fdctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                goto out; -        } - -        op_ret = libgf_client_ftruncate (fdctx->ctx, fd, length); - -out: -        return op_ret; -} - -int -libgf_client_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                                int32_t op_ret, int32_t op_errno, -                                inode_t *inode, struct iatt *buf, -                                struct iatt *preparent, struct iatt *postparent) -{ -        libgf_client_local_t            *local = frame->local; - -        local->reply_stub = fop_link_cbk_stub (frame, NULL, op_ret, op_errno, -                                               inode, buf, preparent, -                                               postparent); - -        LIBGF_REPLY_NOTIFY (local); - -        return 0; -} - -int -libgf_client_link (libglusterfs_client_ctx_t *ctx, loc_t *old, loc_t *new) -{ -        call_stub_t                     *stub = NULL; -        libgf_client_local_t            *local = NULL; -        int                             op_ret = -1; -        inode_t                         *inode = NULL; -        struct iatt                     *sbuf = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, link, local, old, new); - -        op_ret = stub->args.link_cbk.op_ret; -        errno = stub->args.link_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "old %s, new %s, status %d," -                " errno %d", old->path, new->path, op_ret, errno); -        if (op_ret == -1) -                goto out; - -        inode = stub->args.link_cbk.inode; -        sbuf = &stub->args.link_cbk.buf; -        inode_link (inode, new->parent, basename ((char *)new->path), sbuf); -        libgf_transform_iattr (ctx, inode, sbuf); -        inode_lookup (inode); -        libgf_update_iattr_cache (inode, LIBGF_UPDATE_STAT, sbuf); - -out: -        call_stub_destroy (stub); -        return op_ret; -} - -int -glusterfs_glh_link (glusterfs_handle_t handle, const char *oldpath, -                        const char *newpath) -{ -        libglusterfs_client_ctx_t       *ctx = handle; -        int                             op_ret = -1; -        loc_t                           old = {0,}; -        loc_t                           new = {0,}; -        char                            *oldname = NULL; -        char                            *newname = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, oldpath, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, newpath, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "old %s, new %s", oldpath, -                newpath); - -        old.path = strdup (oldpath); -        if (!old.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&old, ctx, 1); -        if (op_ret == -1) { -                errno = ENOENT; -                goto out; -        } - -        oldname = strdup (old.path); -        op_ret = libgf_client_loc_fill (&old, ctx, 0, old.parent->ino, -                                                basename (oldname)); -        if (op_ret == -1) { -                errno = EINVAL; -                goto out; -        } - -        if (IA_ISDIR (old.inode->ia_type)) { -                errno = EPERM; -                op_ret = -1; -                goto out; -        } - -        new.path = strdup (newpath); -        if (!new.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&new, ctx, 1); -        if (op_ret == 0) { -                errno = EEXIST; -                op_ret = -1; -                goto out; -        } - -        newname = strdup (new.path); -        new.inode = inode_ref (old.inode); -        libgf_client_loc_fill (&new, ctx, 0, new.parent->ino, -                        basename (newname)); -        op_ret = libgf_client_link (ctx, &old, &new); - -out: -        if (oldname) -                FREE (oldname); -        if (newname) -                FREE (newname); -        libgf_client_loc_wipe (&old); -        libgf_client_loc_wipe (&new); - -        return op_ret; -} - -int -glusterfs_link (const char *oldpath, const char *newpath) -{ -        int                     op_ret = -1; -        char                    oldvpath[PATH_MAX]; -        char                    newvpath[PATH_MAX]; -        glusterfs_handle_t      oldh = NULL; -        glusterfs_handle_t      newh = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, oldpath, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, newpath, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "old %s, new %s", oldpath, -                newpath); - -        oldh = libgf_resolved_path_handle (oldpath, oldvpath); -        if (!oldh) { -                errno = ENODEV; -                goto out; -        } - -        newh = libgf_resolved_path_handle (newpath, newvpath); -        if (!newh) { -                errno = ENODEV; -                goto out; -        } - -        /* Cannot hard link across glusterfs mounts. */ -        if (newh != oldh) { -                errno = EXDEV; -                goto out; -        } - -        op_ret = glusterfs_glh_link (newh, oldvpath, newvpath); -out: -        return op_ret; -} - -int32_t -libgf_client_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, struct statvfs *buf) -{ -        libgf_client_local_t    *local = frame->local; - -        local->reply_stub = fop_statfs_cbk_stub (frame, NULL, op_ret, op_errno, -                                                 buf); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int32_t -libgf_client_statvfs (libglusterfs_client_ctx_t *ctx, loc_t *loc, -                      struct statvfs *buf) -{ -        call_stub_t             *stub = NULL; -        libgf_client_local_t    *local = NULL; -        int32_t                 op_ret = -1; - -        /* statfs fop receives struct statvfs as an argument */ - -        /* libgf_client_statfs_cbk will be the callback, not -           libgf_client_statvfs_cbk. see definition of LIBGF_CLIENT_FOP -        */ -        LIBGF_CLIENT_FOP (ctx, stub, statfs, local, loc); - -        op_ret = stub->args.statfs_cbk.op_ret; -        errno = stub->args.statfs_cbk.op_errno; -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, status %d, errno %d", -                loc->path, op_ret, errno); -        if (op_ret == -1) -                goto out; - -        if (buf) -                memcpy (buf, &stub->args.statfs_cbk.buf, sizeof (*buf)); -out: -        call_stub_destroy (stub); -        return op_ret; -} - -int -glusterfs_glh_statfs (glusterfs_handle_t handle, const char *path, -                        struct statfs *buf) -{ -        struct statvfs                  stvfs = {0, }; -        int32_t                         op_ret = -1; -        loc_t                           loc = {0, }; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *name = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path lookup failed for (%s)", loc.path); -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                        basename (name)); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1, " -                                "returning EINVAL"); -                        errno = EINVAL; -                goto out; -        } - -        op_ret = libgf_client_statvfs (ctx, &loc, &stvfs); -        if (op_ret == 0) { -#ifdef GF_SOLARIS_HOST_OS -		buf->f_fstyp = 0; -                buf->f_bsize = stvfs.f_bsize; -                buf->f_blocks = stvfs.f_blocks; -                buf->f_bfree = stvfs.f_bfree; -		buf->f_files = stvfs.f_bavail; -                buf->f_ffree = stvfs.f_ffree; -#else -                buf->f_type = 0; -                buf->f_bsize = stvfs.f_bsize; -                buf->f_blocks = stvfs.f_blocks; -                buf->f_bfree = stvfs.f_bfree; -                buf->f_bavail = stvfs.f_bavail; -                buf->f_files = stvfs.f_bavail; -                buf->f_ffree = stvfs.f_ffree; -                /* FIXME: buf->f_fsid has either "val" or "__val" as member -                   based on conditional macro expansion. see definition of -                   fsid_t - Raghu -                   It seems have different structure member names on -                   different archs, so I am stepping down to doing a struct -                   to struct copy. :Shehjar -                */ -                memcpy (&buf->f_fsid, &stvfs.f_fsid, sizeof (stvfs.f_fsid)); -                buf->f_namelen = stvfs.f_namemax; -#endif -        } - -out: -        if (name) -                FREE (name); -        libgf_client_loc_wipe (&loc); -        return op_ret; -} - -int -glusterfs_statfs (const char *path, struct statfs *buf) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h      = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, buf, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_statfs (h, vpath, buf); -out: -        return op_ret; -} - -int -glusterfs_glh_statvfs (glusterfs_handle_t handle, const char *path, -                                struct statvfs *buf) -{ -        int32_t                         op_ret = -1; -        loc_t                           loc = {0, }; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *name = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path lookup failed for (%s)", loc.path); -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -	if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1, returning" -                                " EINVAL"); -                errno = EINVAL; -                goto out; -	} - -        op_ret = libgf_client_statvfs (ctx, &loc, buf); -        if (op_ret != -1) -                /* Should've been a call to libgf_transform_iattr but -                 * that only handles struct stat -                 */ -                buf->f_fsid = (unsigned long)ctx->fake_fsid; - -out: -        if (name) -                FREE (name); -        libgf_client_loc_wipe (&loc); -        return op_ret; -} - -int -glusterfs_statvfs (const char *path, struct statvfs *buf) -{ -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h      = NULL; -        int                     op_ret = -1; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, buf, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_statvfs (h, vpath, buf); -out: -        return op_ret; -} - -int32_t -libgf_client_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, struct iatt *buf, -                         struct iatt *preoldparent, struct iatt *postoldparent, -                         struct iatt *prenewparent, struct iatt *postnewparent) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_rename_cbk_stub (frame, NULL, op_ret, op_errno, -                                                 buf, preoldparent, -                                                 postoldparent, prenewparent, -                                                 postnewparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int32_t -libgf_client_rename (libglusterfs_client_ctx_t *ctx, loc_t *oldloc, -                     loc_t *newloc) -{ -        int                             op_ret = -1; -        libgf_client_local_t            *local = NULL; -        call_stub_t                     *stub = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, rename, local, oldloc, newloc); - -        op_ret = stub->args.rename_cbk.op_ret; -        errno = stub->args.rename_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "old %s, new %s, status %d, errno" -                " %d", oldloc->path, newloc->path, op_ret, errno); -        if (op_ret == -1) -                goto out; - -        if (!libgf_get_inode_ctx (newloc->inode)) -                libgf_alloc_inode_ctx (ctx, newloc->inode); - -        libgf_transform_iattr (ctx, newloc->inode, &stub->args.rename_cbk.buf); -        libgf_update_iattr_cache (newloc->inode, LIBGF_UPDATE_STAT, -                                        &stub->args.rename_cbk.buf); - -        inode_unlink (oldloc->inode, oldloc->parent, oldloc->name); -out: -        call_stub_destroy (stub); -        return op_ret; -} - -int -glusterfs_glh_rename (glusterfs_handle_t handle, const char *oldpath, -                      const char *newpath) -{ -        int32_t                         op_ret = -1; -        loc_t                           oldloc = {0, }, newloc = {0, }; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *newname = NULL; -        char                            *oldname = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, oldpath, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, newpath, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "old %s, new %s", oldpath, -                newpath); - -        oldloc.path = strdup (oldpath); -        if (!oldloc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&oldloc, ctx, 1); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path lookup failed for (%s)", oldloc.path); -                goto out; -        } - -        newloc.path = strdup (newpath); -        if (!newloc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&newloc, ctx, 1); - -        oldname = strdup (oldloc.path); -        op_ret = libgf_client_loc_fill (&oldloc, ctx, 0, oldloc.parent->ino, -                                        basename (oldname)); -	if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1," -                                " returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        newname = strdup (newloc.path); -        op_ret = libgf_client_loc_fill (&newloc, ctx, 0, newloc.parent->ino, -                                        basename (newname)); -	if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1," -                                " returning EINVAL"); -                errno = EINVAL; -                goto out; -        } -        op_ret = libgf_client_rename (ctx, &oldloc, &newloc); - -out: -        if (oldname) -                FREE (oldname); -        if (newname) -                FREE (newname); -        libgf_client_loc_wipe (&newloc); -        libgf_client_loc_wipe (&oldloc); - -        return op_ret; -} - - -int -glusterfs_rename (const char *oldpath, const char *newpath) -{ -        int                     op_ret = -1; -        char                    oldvpath[PATH_MAX]; -        char                    newvpath[PATH_MAX]; -        glusterfs_handle_t      oldh = NULL; -        glusterfs_handle_t      newh = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, oldpath, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, newpath, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Old %s, new %s", oldpath, -                newpath); - -        oldh = libgf_resolved_path_handle (oldpath, oldvpath); -        if (!oldh) { -                errno = ENODEV; -                goto out; -        } - -        newh = libgf_resolved_path_handle (newpath, newvpath); -        if (!newh) { -                errno = ENODEV; -                goto out; -        } - -        if (oldh != newh) { -                errno = EXDEV; -                goto out; -        } - -        op_ret = glusterfs_glh_rename (oldh, oldvpath, newvpath); -out: -        return op_ret; -} - - -int -glusterfs_glh_utimes (glusterfs_handle_t handle, const char *path, -                        const struct timeval times[2]) -{ -        int32_t                         op_ret = -1; -        loc_t                           loc = {0, }; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *name = NULL; -        struct iatt                     stbuf = {0,}; -        int32_t                         valid = 0; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); -        stbuf.ia_atime = times[0].tv_sec; -        stbuf.ia_atime_nsec = times[0].tv_usec * 1000; -        stbuf.ia_mtime = times[1].tv_sec; -        stbuf.ia_mtime_nsec = times[1].tv_usec * 1000; - -        valid |= (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path lookup failed for (%s)", loc.path); -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1" -                                " returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        op_ret = libgf_client_setattr (ctx, &loc, &stbuf, valid); -out: -        if (name) -                FREE (name); -        libgf_client_loc_wipe (&loc); -        return op_ret; -} - -int -glusterfs_utimes (const char *path, const struct timeval times[2]) -{ -        char                    vpath[PATH_MAX]; -        int                     op_ret = -1; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_utimes (h, vpath, times); -out: -        return op_ret; -} - -int -glusterfs_glh_utime (glusterfs_handle_t handle, const char *path, -                        const struct utimbuf *buf) -{ -        int32_t                         op_ret = -1; -        loc_t                           loc = {0, }; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *name = NULL; -        struct iatt                     stbuf = {0,}; -        int32_t                         valid = 0; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); -        if (buf) { -                stbuf.ia_atime = buf->actime; -                stbuf.ia_atime_nsec = 0; - -                stbuf.ia_mtime = buf->modtime; -                stbuf.ia_mtime_nsec = 0; -        } - -        valid |= (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path lookup failed for (%s)", loc.path); -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1," -                                " returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        op_ret = libgf_client_setattr (ctx, &loc, &stbuf, valid); -out: -        if (name) -                FREE (name); -        libgf_client_loc_wipe (&loc); -        return op_ret; -} - -int -glusterfs_utime (const char *path, const struct utimbuf *buf) -{ -        char                    vpath[PATH_MAX]; -        int                     op_ret = -1; -        glusterfs_handle_t      h      = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, buf, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_utime (h, vpath, buf); -out: -        return op_ret; -} - -static int32_t -libgf_client_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                                int32_t op_ret, int32_t op_errno, -                                inode_t *inode, struct iatt *buf, -                                struct iatt *preparent, struct iatt *postparent) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_mknod_cbk_stub (frame, NULL, op_ret, op_errno, -                                                inode, buf, preparent, -                                                postparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -static int32_t -libgf_client_mknod (libglusterfs_client_ctx_t *ctx, loc_t *loc, mode_t mode, -                    dev_t rdev) -{ -        int32_t                 op_ret = -1; -        call_stub_t             *stub = NULL; -        libgf_client_local_t    *local = NULL; -        inode_t                 *inode = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, mknod, local, loc, mode, rdev); - -        op_ret = stub->args.mknod_cbk.op_ret; -        errno = stub->args.mknod_cbk.op_errno; -        if (op_ret == -1) -                goto out; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, status %d, errno %d", -                loc->path, op_ret, errno); -        inode = stub->args.mknod_cbk.inode; -        inode_link (inode, loc->parent, loc->name, &stub->args.mknod_cbk.buf); -        libgf_transform_iattr (ctx, inode, &stub->args.mknod_cbk.buf); -        inode_lookup (inode); - -        if (!libgf_alloc_inode_ctx (ctx, inode)) -                libgf_alloc_inode_ctx (ctx, inode); - -        libgf_update_iattr_cache (inode, LIBGF_UPDATE_STAT, -                                        &stub->args.mknod_cbk.buf); - -out: -	call_stub_destroy (stub); -        return op_ret; -} - -int -glusterfs_glh_mknod(glusterfs_handle_t handle, const char *path, mode_t mode, -                        dev_t dev) -{ -        libglusterfs_client_ctx_t       *ctx = handle; -        loc_t                           loc = {0, }; -        char                            *name = NULL; -        int32_t                         op_ret = -1; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == 0) { -                op_ret = -1; -                errno = EEXIST; -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 0); -        if (op_ret == -1) { -                errno = ENOENT; -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -	if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1, " -                                " returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        loc.inode = inode_new (ctx->itable); -        op_ret = libgf_client_mknod (ctx, &loc, mode, dev); - -out: -	libgf_client_loc_wipe (&loc); -	if (name) -                FREE (name); - -	return op_ret; -} - -int -glusterfs_mknod(const char *pathname, mode_t mode, dev_t dev) -{ -        char                    vpath[PATH_MAX];  -        int                     op_ret = -1; -        glusterfs_handle_t      h      = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, pathname, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", pathname); - -        h = libgf_resolved_path_handle (pathname, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -out: -        return op_ret; -} - -int -glusterfs_glh_mkfifo (glusterfs_handle_t handle, const char *path, mode_t mode) -{ - -        libglusterfs_client_ctx_t       *ctx = handle; -        loc_t                           loc = {0, }; -        char                            *name = NULL; -        int32_t                         op_ret = -1; -        dev_t                           dev = 0; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); -        loc.path = libgf_resolve_path_light ((char *)path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Failed to resolve name"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == 0) { -                op_ret = -1; -                errno = EEXIST; -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 0); -        if (op_ret == -1) { -                errno = ENOENT; -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1, " -                                "returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        loc.inode = inode_new (ctx->itable); -        op_ret = libgf_client_mknod (ctx, &loc, mode | S_IFIFO, dev); - -out: -	libgf_client_loc_wipe (&loc); -        if (name) -                free (name); - -        return op_ret; -} - -int -glusterfs_mkfifo (const char *path, mode_t mode) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_mkfifo (h, vpath, mode); -out: -        return op_ret; -} - -int32_t -libgf_client_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, -                         struct iatt *preparent, struct iatt *postparent) -{ -        libgf_client_local_t    *local = frame->local; - -        local->reply_stub = fop_unlink_cbk_stub (frame, NULL, op_ret, op_errno, -                                                 preparent, postparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int -libgf_client_unlink (libglusterfs_client_ctx_t *ctx, loc_t *loc) -{ -        int                             op_ret = -1; -        libgf_client_local_t            *local = NULL; -        call_stub_t                     *stub = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, unlink, local, loc); - -        op_ret = stub->args.unlink_cbk.op_ret; -        errno = stub->args.unlink_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", loc->path); -        if (op_ret == -1) -                goto out; - -        inode_unlink (loc->inode, loc->parent, loc->name); - -out: -        call_stub_destroy (stub); -        return op_ret; -} - -int -glusterfs_glh_unlink (glusterfs_handle_t handle, const char *path) -{ -        int32_t                         op_ret = -1; -        loc_t                           loc = {0, }; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *name = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path lookup failed for (%s)", loc.path); -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -	if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1, " -                                " returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        op_ret = libgf_client_unlink (ctx, &loc); - -out: -        if (name) -                FREE (name); -        libgf_client_loc_wipe (&loc); -        return op_ret; -} - -int -glusterfs_unlink (const char *path) -{ -        char                    vpath[PATH_MAX]; -        int                     op_ret = -1; -        glusterfs_handle_t      h      = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_unlink (h, vpath); - -out: -        return op_ret; -} - -static int32_t -libgf_client_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                                int32_t op_ret, int32_t op_errno, -                                inode_t *inode, struct iatt *buf, -                                struct iatt *preparent, struct iatt *postparent) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_symlink_cbk_stub (frame, NULL, op_ret, -                                                  op_errno, inode, buf, -                                                  preparent, postparent); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int32_t -libgf_client_symlink (libglusterfs_client_ctx_t *ctx, const char *linkpath, -                      loc_t *loc) -{ -        int                     op_ret = -1; -        libgf_client_local_t    *local = NULL; -        call_stub_t             *stub = NULL; -        inode_t                 *inode = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, symlink, local, linkpath, loc); - -        op_ret = stub->args.symlink_cbk.op_ret; -        errno = stub->args.symlink_cbk.op_errno; -        if (op_ret == -1) -                goto out; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "target: %s, link: %s, status %d" -                " errno %d", linkpath, loc->path, op_ret, errno); -        inode = stub->args.symlink_cbk.inode; -        inode_link (inode, loc->parent, loc->name, -                        &stub->args.symlink_cbk.buf); -        libgf_transform_iattr (ctx, inode, &stub->args.symlink_cbk.buf); -        inode_lookup (inode); -        if (!libgf_get_inode_ctx (inode)) -                libgf_alloc_inode_ctx (ctx, inode); - -        libgf_update_iattr_cache (inode, LIBGF_UPDATE_STAT, -                                        &stub->args.symlink_cbk.buf); -out: -        call_stub_destroy (stub); -        return op_ret; -} - -int -glusterfs_glh_symlink (glusterfs_handle_t handle, const char *oldpath, -                       const char *newpath) -{ -        int32_t                         op_ret = -1; -        libglusterfs_client_ctx_t       *ctx = handle; -        loc_t                           oldloc = {0, }; -        loc_t                           newloc = {0, }; -        char                            *oldname = NULL; -        char                            *newname = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, newpath, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "target: %s, link: %s", oldpath, -                newpath); -        /* Old path does not need to be interpreted or looked up */ -        oldloc.path = strdup (oldpath); - -	newloc.path = strdup (newpath); -        if (!newloc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -	op_ret = libgf_client_path_lookup (&newloc, ctx, 1); -	if (op_ret == 0) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "new path (%s) already exists, " -                        " returning EEXIST", newloc.path); -                op_ret = -1; -                errno = EEXIST; -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&newloc, ctx, 0); -        if (op_ret == -1) { -                errno = ENOENT; -                goto out; -        } - -        newloc.inode = inode_new (ctx->itable); -        newname = strdup (newloc.path); -        op_ret = libgf_client_loc_fill (&newloc, ctx, 0, newloc.parent->ino, -                                                basename (newname)); - -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1, " -                                "returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        op_ret = libgf_client_symlink (ctx, oldpath, &newloc); - -out: -        if (newname) -                FREE (newname); - -        if (oldname) -                FREE (oldname); -        libgf_client_loc_wipe (&oldloc); -        libgf_client_loc_wipe (&newloc); -        return op_ret; -} - -int -glusterfs_symlink (const char *oldpath, const char *newpath) -{ -        char                    vpath[PATH_MAX]; -        int                     op_ret = -1; -        glusterfs_handle_t      h      = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, oldpath, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, newpath, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "target: %s, link: %s", oldpath, -                newpath); - -        h = libgf_resolved_path_handle (newpath, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_symlink (h, oldpath, vpath); -out: -        return op_ret; -} - - -int32_t -libgf_client_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                                int32_t op_ret, int32_t op_errno, -                                const char *path, struct iatt *sbuf) -{ -        libgf_client_local_t    *local = frame->local; - -        local->reply_stub = fop_readlink_cbk_stub (frame, NULL, op_ret, -                                                   op_errno, path, sbuf); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int32_t -libgf_client_readlink (libglusterfs_client_ctx_t *ctx, loc_t *loc, char *buf, -                       size_t bufsize) -{ -        int                             op_ret = -1; -        libgf_client_local_t            *local = NULL; -        call_stub_t                     *stub = NULL; -        size_t                           cpy_size = 0; - -        LIBGF_CLIENT_FOP (ctx, stub, readlink, local, loc, bufsize); - -        op_ret = stub->args.readlink_cbk.op_ret; -        errno = stub->args.readlink_cbk.op_errno; - -        if (op_ret != -1) { -                cpy_size = ((op_ret <= bufsize) ? op_ret : bufsize); -                memcpy (buf, stub->args.readlink_cbk.buf, cpy_size); -                op_ret = cpy_size; -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "link: %s, target: %s," -                        " status %d, errno %d", loc->path, buf, op_ret, errno); -        } else -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "link: %s, status %d, " -                        "errno %d", loc->path, op_ret, errno); - -        call_stub_destroy (stub); -        return op_ret; -} - -ssize_t -glusterfs_glh_readlink (glusterfs_handle_t handle, const char *path, char *buf, -                                size_t bufsize) -{ -        int32_t                         op_ret = -1; -        loc_t                           loc = {0, }; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *name = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); -        if (bufsize < 0) { -                errno = EINVAL; -                goto out; -        } - -        if (bufsize == 0) { -                op_ret = 0; -                goto out; -        } - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                        "path lookup failed for (%s)", loc.path); -                goto out; -        } - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                                basename (name)); -        if (op_ret == -1) { -                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                "libgf_client_loc_fill returned -1, " -                                "returning EINVAL"); -                errno = EINVAL; -                goto out; -        } - -        op_ret = libgf_client_readlink (ctx, &loc, buf, bufsize); - -out: -        if (name) -                FREE (name); - -        libgf_client_loc_wipe (&loc); -        return op_ret; -} - -ssize_t -glusterfs_readlink (const char *path, char *buf, size_t bufsize) -{ -        char                    vpath[PATH_MAX]; -        int                     op_ret = -1; -        glusterfs_handle_t      h      = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, buf, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_readlink (h, vpath, buf, bufsize); -out: -        return op_ret; -} - -char * -glusterfs_glh_realpath (glusterfs_handle_t handle, const char *path, -                                char *resolved_path) -{ -        char                            *buf = NULL; -        char                            *rpath = NULL; -        char                            *start = NULL, *end = NULL; -        char                            *dest = NULL; -        libglusterfs_client_ctx_t       *ctx = handle; -        long int                        path_max = 0; -        char                            *ptr = NULL; -        struct stat                     stbuf = {0, }; -        long int                        new_size = 0; -        char                            *new_rpath = NULL; -        int                             dest_offset = 0; -        char                            *rpath_limit = 0; -        int                             ret = 0, num_links = 0; -        char                            *vpath = NULL, *tmppath = NULL; -        char                             absolute_path[PATH_MAX]; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -#ifdef PATH_MAX -        path_max = PATH_MAX; -#else -        path_max = pathconf (path, _PC_PATH_MAX); -        if (path_max <= 0) { -                path_max = 1024; -        } -#endif - -        if (resolved_path == NULL) { -                rpath = CALLOC (1, path_max); -                if (rpath == NULL) { -                        errno = ENOMEM; -                        goto out; -                } -        } else { -                rpath = resolved_path; -        } - -        rpath_limit = rpath + path_max; - -        if (path[0] == '/') { -                rpath[0] = '/'; -                dest = rpath + 1; -        } else { -                /* -                   FIXME: can $CWD be a valid path on glusterfs server? hence is -                   it better to handle this case or just return EINVAL for -                   relative paths? -                */ -                ptr = getcwd (rpath, path_max); -                if (ptr == NULL) { -                        goto err; -                } -                dest = rpath + strlen (rpath); -        } - -        for (start = end = (char *)path; *end; start = end) { -                if (dest[-1] != '/') { -                        *dest++ = '/'; -                } - -                while (*start == '/') { -                        start++; -                } - -                for (end = start; *end && *end != '/'; end++); - -                if ((end - start) == 0) { -                        break; -                } - -                if ((end - start == 1) && (start[0] == '.')) { -                        /* do nothing */ -                } else if (((end - start) == 2) && (start[0] == '.') -                           && (start[1] == '.')) { -                        if (dest > rpath + 1) { -                                while (--dest[-1] != '/'); -                        } -                } else { -                        if ((dest + (end - start + 1)) >= rpath_limit) { -                                if (resolved_path == NULL) { -                                        errno = ENAMETOOLONG; -                                        if (dest > rpath + 1) -                                                dest--; -                                        *dest = '\0'; -                                        goto err; -                                } - -                                dest_offset = dest - rpath; -                                new_size = rpath_limit - rpath; -                                if ((end - start + 1) > path_max) { -                                        new_size = (end - start + 1); -                                } else { -                                        new_size = path_max; -                                } - -                                new_rpath = realloc (rpath, new_size); -                                if (new_rpath == NULL) { -                                        goto err; -                                } - - -                                dest = new_rpath + dest_offset; -                                rpath = new_rpath; -                                rpath_limit = rpath + new_size; -                        } - -                        memcpy (dest, start, end - start); -                        dest +=  end - start; -                        *dest = '\0'; - -                        ret = glusterfs_glh_lstat (handle, rpath, &stbuf); -                        if (ret == -1) { -                                gf_log ("libglusterfsclient", GF_LOG_ERROR, -                                        "glusterfs_glh_stat returned -1 for" -                                        " path (%s):(%s)", rpath, -                                        strerror (errno)); -                                goto err; -                        } - -                        if (S_ISLNK (stbuf.st_mode)) { -                                buf = calloc (1, path_max); -                                if (buf == NULL) { -                                        errno = ENOMEM; -                                        goto err; -                                } - -                                if (++num_links > MAXSYMLINKS) -                                { -                                        errno = ELOOP; -                                        FREE (buf); -                                        goto err; -                                } - -                                ret = glusterfs_glh_readlink (handle, rpath, -                                                              buf, -                                                              path_max - 1); -                                if (ret < 0) { -                                        gf_log ("libglusterfsclient", -                                                GF_LOG_ERROR, -                                                "glusterfs_readlink returned %d" -                                                " for path (%s):(%s)", -                                                ret, rpath, strerror (errno)); -                                        FREE (buf); -                                        goto err; -                                } -                                buf[ret] = '\0'; - -                                if (buf[0] != '/') { -                                        tmppath = strdup (rpath); -                                        tmppath = dirname (tmppath); -                                        sprintf (absolute_path, "%s/%s", -                                                 tmppath, buf); -                                        FREE (buf); -                                        buf = libgf_resolve_path_light ((char *)absolute_path); -                                        FREE (tmppath); -                                } - -                                rpath = glusterfs_glh_realpath (handle, buf, -                                                                rpath); -                                FREE (buf); -                                if (rpath == NULL) { -                                        goto out; -                                } -                                dest = rpath + strlen (rpath); - -                        } else if (!S_ISDIR (stbuf.st_mode) && *end != '\0') { -                                errno = ENOTDIR; -                                goto err; -                        } -                } -        } -        if (dest > rpath + 1 && dest[-1] == '/') -                --dest; -        *dest = '\0'; - -out: -        if (vpath) -                FREE (vpath); -        return rpath; - -err: -        if (vpath) -                FREE (vpath); -        if (resolved_path == NULL) { -                FREE (rpath); -        } - -        return NULL; -} - -char * -glusterfs_realpath (const char *path, char *resolved_path) -{ -        char                    *res   = NULL; -        char                     vpath[PATH_MAX]; -        glusterfs_handle_t       h     = NULL; -        char                    *realp = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        realp = CALLOC (PATH_MAX, sizeof (char)); -        if (!realp) -                goto out; - -        libgf_vmp_search_vmp (h, realp, PATH_MAX); -        res = glusterfs_glh_realpath (h, vpath, resolved_path); -        if (!res) -                goto out; - -        /* This copy is needed to ensure that when we return the real resolved -         * path, we return a path that accounts for the app's view of the -         * path, i.e. it starts with the VMP, in case this is an absolute path. -         */ -        if (libgf_path_absolute (path)) { -                strcat (realp, resolved_path); -                strcpy (resolved_path, realp); -        } - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, resolved %s", path, -                resolved_path); -out: -        if (realp) -                FREE (realp); - -        return res; -} - -int -glusterfs_glh_remove (glusterfs_handle_t handle, const char *path) -{ -        loc_t                           loc = {0, }; -        int                             op_ret = -1; -        libglusterfs_client_ctx_t       *ctx = handle; -        char                            *name = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, handle, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", path); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -        op_ret = libgf_client_path_lookup (&loc, ctx, 1); -        if (op_ret == -1) -                goto out; - -        name = strdup (loc.path); -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, -                                        basename (name)); -        if (op_ret == -1) -                goto out; - -        if (IA_ISDIR (loc.inode->ia_type)) -                op_ret = libgf_client_rmdir (ctx, &loc); -        else -                op_ret = libgf_client_unlink (ctx, &loc); - -out: -        if (name) -                FREE (name); -        return op_ret; - -} - -int -glusterfs_remove(const char *pathname) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, pathname, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s", pathname); - -        h = libgf_resolved_path_handle (pathname, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_remove (h, vpath); -out: -        return op_ret; -} - -void -glusterfs_rewinddir (glusterfs_dir_t dirfd) -{ -        libglusterfs_client_fd_ctx_t    *fd_ctx = NULL; - -        fd_ctx = libgf_get_fd_ctx ((fd_t *)dirfd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                fd_ctx->offset = 0; -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Offset: %"PRIu64, -                        fd_ctx->offset); -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -out: -        return; -} - -void -glusterfs_seekdir (glusterfs_dir_t dirfd, off_t offset) -{ -        libglusterfs_client_fd_ctx_t    *fd_ctx = NULL; - -        fd_ctx = libgf_get_fd_ctx ((fd_t *)dirfd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                fd_ctx->offset = offset; -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Offset: %"PRIu64, -                        fd_ctx->offset); -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -out: -        return; -} - -off_t -glusterfs_telldir (glusterfs_dir_t dirfd) -{ -        libglusterfs_client_fd_ctx_t    *fd_ctx = NULL; -	off_t                           off = -1; - -        fd_ctx = libgf_get_fd_ctx ((fd_t *)dirfd); -        if (!fd_ctx) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "No fd context present"); -                errno = EBADF; -                goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                off = fd_ctx->offset; -                gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "Offset: %"PRIu64, -                        fd_ctx->offset); -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -out: -        return off; -} - -struct libgf_client_sendfile_data { -        int                reads_sent; -        int                reads_completed; -        int                out_fd; -        int32_t            op_ret; -        int32_t            op_errno; -        pthread_mutex_t    lock; -        pthread_cond_t     cond; -}; - -int -libgf_client_sendfile_read_cbk (int op_ret, int op_errno, -                                glusterfs_iobuf_t *buf, void *cbk_data) -{ -        struct libgf_client_sendfile_data *sendfile_data = cbk_data; -        int                                bytes = 0; - -        if (op_ret > 0) { -                bytes = writev (sendfile_data->out_fd, buf->vector, buf->count); -                if (bytes != op_ret) { -                        op_ret = -1; -                        op_errno = errno; -                } - -                glusterfs_free (buf); -        } - -        pthread_mutex_lock (&sendfile_data->lock); -        { -                if (sendfile_data->op_ret != -1) { -                        if (op_ret == -1) { -                                sendfile_data->op_ret = -1; -                                sendfile_data->op_errno = op_errno; -                        } else { -                                sendfile_data->op_ret += op_ret; -                        } -                } - -                sendfile_data->reads_completed++; - -                if (sendfile_data->reads_completed -                    == sendfile_data->reads_sent) { -                        pthread_cond_broadcast (&sendfile_data->cond); -                }  -        } -        pthread_mutex_unlock (&sendfile_data->lock); - -        return 0; -} - - -ssize_t -glusterfs_sendfile (int out_fd, glusterfs_file_t in_fd, off_t *offset, -                    size_t count) -{ -        ssize_t                           ret = -1; -        struct libgf_client_sendfile_data cbk_data = {0, }; -        off_t                             off = -1; -        size_t                            size = 0; -        int                               flags = 0; -        int                               non_block = 0; - -         -        pthread_mutex_init (&cbk_data.lock, NULL); -        pthread_cond_init (&cbk_data.cond, NULL); -        cbk_data.out_fd = out_fd; -         -        if (offset) { -                off = *offset; -        } - -        flags = fcntl (out_fd, F_GETFL); - -        if (flags != -1) { -                non_block = flags & O_NONBLOCK; - -                if (non_block) { -                        ret = fcntl (out_fd, F_SETFL, flags & ~O_NONBLOCK); -                } -        } - -        while (count != 0) { -                /*  -                 * FIXME: what's the optimal size for reads and writes? -                 */ -                size = (count > LIBGF_SENDFILE_BLOCK_SIZE) ?  -                        LIBGF_SENDFILE_BLOCK_SIZE : count; - -                /*  -                 * we don't wait for reply to previous read, we just send all -                 * reads in a single go. -                 */ -                ret = glusterfs_read_async (in_fd, size, off, -                                            libgf_client_sendfile_read_cbk, -                                            &cbk_data); -                if (ret == -1) { -                        break; -                } - -                pthread_mutex_lock (&cbk_data.lock); -                { -                        cbk_data.reads_sent++; -                } -                pthread_mutex_unlock (&cbk_data.lock); - -                if (offset) { -                        off += size; -                } - -                count -= size; -        } - -        pthread_mutex_lock (&cbk_data.lock); -        { -                /*  -                 * if we've not received replies to all the reads we've sent, -                 * wait for them -                 */ -                if (cbk_data.reads_sent > cbk_data.reads_completed) { -                        pthread_cond_wait (&cbk_data.cond, -                                           &cbk_data.lock); -                } -        } -        pthread_mutex_unlock (&cbk_data.lock); - -        if (offset != NULL) { -                *offset = off; -        } -  -        /* if we were able to stack_wind all the reads */ - -        if (ret == 0) { -                ret = cbk_data.op_ret; -                errno = cbk_data.op_errno; -        } - -        if (non_block) { -                fcntl (out_fd, F_SETFL, flags); -        } - -        return ret; -} - - -static int32_t -libgf_client_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, struct flock *lock) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_lk_cbk_stub (frame, NULL, op_ret, op_errno, -                                             lock); - -        LIBGF_REPLY_NOTIFY (local); - -        return 0; -} - - -int -libgf_client_lk (libglusterfs_client_ctx_t *ctx, fd_t *fd, int cmd, -                 struct flock *lock) -{ -        call_stub_t          *stub = NULL; -        int32_t               op_ret; -        libgf_client_local_t *local = NULL; -         -        LIBGF_CLIENT_FOP(ctx, stub, lk, local, fd, cmd, lock); - -        op_ret = stub->args.lk_cbk.op_ret; -        errno = stub->args.lk_cbk.op_errno; -        if (op_ret == 0) { -                *lock = stub->args.lk_cbk.lock; -        } - -	call_stub_destroy (stub); -        return op_ret; -} - - -int -glusterfs_fcntl (glusterfs_file_t fd, int cmd, ...) -{ -        int                           ret = -1; -        struct flock                 *lock = NULL; -        va_list                       ap; -        libglusterfs_client_ctx_t    *ctx = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        ctx = fd_ctx->ctx; - -        switch (cmd) { -        case F_SETLK: -        case F_SETLKW: -        case F_GETLK: -#if F_SETLK != F_SETLK64 -        case F_SETLK64: -#endif -#if F_SETLKW != F_SETLKW64 -        case F_SETLKW64: -#endif -#if F_GETLK != F_GETLK64 -        case F_GETLK64: -#endif -                va_start (ap, cmd); -                lock = va_arg (ap, struct flock *); -                va_end (ap); - -                if (!lock) { -                        errno = EINVAL; -                        goto out; -                } - -                ret = libgf_client_lk (ctx, fd, cmd, lock);  -                break; - -        default: -                errno = EINVAL; -                break; -        } - -out: -        return ret; -} - - -int -libgf_client_chdir (const char *path) -{ -        int                op_ret            = 0; -        uint32_t           resulting_cwd_len = 0; - -        pthread_mutex_lock (&cwdlock); -        { -                if (!libgf_path_absolute (path)) { -                        resulting_cwd_len = strlen (path) + strlen (cwd) -                                + ((strlen (path) && path[strlen (path) - 1] == '/') -                                   ? 0 : 1) + 1; - -                        if (resulting_cwd_len > PATH_MAX) { -                                op_ret = -1; -                                errno = ENAMETOOLONG; -                                goto unlock; -                        } -                        strcat (cwd, path); -                } else { -                        resulting_cwd_len = strlen (path) -                                + ((path[strlen (path) - 1] == '/') -                                   ? 0 : 1) + 1; -                                 -                        if (resulting_cwd_len > PATH_MAX) { -                                op_ret = -1; -                                errno = ENAMETOOLONG; -                                goto unlock; -                        } - -                        strcpy (cwd, path); -                } - -                if (cwd[strlen (cwd) - 1] != '/') { -                        strcat (cwd, "/"); -                } -        } -unlock: -        pthread_mutex_unlock (&cwdlock); - -        return op_ret; -} - - -int -glusterfs_fchdir (glusterfs_file_t fd) -{ -        int                           op_ret = -1; -        char                          vpath[PATH_MAX]; -        char                          vmp[PATH_MAX];  -        char                         *res    = NULL; -        libglusterfs_client_fd_ctx_t *fd_ctx = NULL; -        glusterfs_handle_t            handle = NULL; -         -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, fd, out); - -        /* FIXME: there is a race-condition between glusterfs_fchdir and -           glusterfs_close. If two threads of application call glusterfs_fchdir -           and glusterfs_close on the same fd, there is a possibility of -           glusterfs_fchdir accessing freed memory of fd_ctx. -        */ - -        fd_ctx = libgf_get_fd_ctx (fd); -        if (!fd_ctx) { -                errno = EBADF; -		goto out; -        } - -        pthread_mutex_lock (&fd_ctx->lock); -        { -                handle = fd_ctx->ctx; -                strcpy (vpath, fd_ctx->vpath); -        } -        pthread_mutex_unlock (&fd_ctx->lock); - -        if (vpath[0] == '\0') { -                errno = ENOTDIR; -                goto out; -        } - -        res = libgf_vmp_search_vmp (handle, vmp, PATH_MAX); -        if (res == NULL) { -                errno = EBADF; -                goto out; -        } - -        /* both vmp and vpath are terminated with '/'. Also path starts with a -           '/'. Hence the extra '/' amounts to NULL character at the end of the -           string. -        */ -        if ((strlen (vmp) + strlen (vpath)) > PATH_MAX) { -                errno = ENAMETOOLONG; -                goto out; -        } - -        pthread_mutex_lock (&cwdlock); -        { -                strcpy (cwd, vmp); -                res = vpath; -                if (res[0] == '/') { -                        res++; -                } - -                strcat (cwd, res); -        } -        pthread_mutex_unlock (&cwdlock); - -        op_ret = 0;  -out: -        return op_ret; -} - - -int -glusterfs_chdir (const char *path) -{ -        int32_t            op_ret            = -1; -        glusterfs_handle_t handle            = NULL; -        loc_t              loc               = {0, }; -        char               vpath[PATH_MAX];  - -        handle = libgf_resolved_path_handle (path, vpath); - -        if (handle != NULL)  { -                loc.path = strdup (vpath); -                if (!loc.path) { -                        gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Path compaction " -                                "failed"); -                        goto out; -                } - -                op_ret = libgf_client_path_lookup (&loc, handle, 0); -        } - -        if ((handle == NULL) || (op_ret == 0)) { -                op_ret = libgf_client_chdir (path); -        } - -out: -        return op_ret; -} - - -char * -glusterfs_getcwd (char *buf, size_t size) -{ -        char              *res      = NULL; -        size_t             len      = 0;  -        loc_t              loc      = {0, }; -        glusterfs_handle_t handle   = NULL; -        char               vpath[PATH_MAX]; -        int32_t            op_ret   = 0;  - -        pthread_mutex_lock (&cwdlock); -        { -                if (!cwd_inited) { -                        errno = ENODEV; -                        goto unlock; -                } - -                if (buf == NULL) { -                        buf = CALLOC (1, len); -                        if (buf == NULL) { -                                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, -                                        "out of memory"); -                                goto unlock; -                        } -                } else { -                        if (size == 0) { -                                errno = EINVAL; -                                goto unlock; -                        } - -                        if (len > size) { -                                errno = ERANGE; -                                goto unlock; -                        } -                } - -                strcpy (buf, cwd); -                res = buf;  -        } -unlock: -        pthread_mutex_unlock (&cwdlock); - -        if (res != NULL) { -                handle = libgf_resolved_path_handle (res, vpath); - -                if (handle != NULL)  { -                        loc.path = strdup (vpath); -                        if (loc.path == NULL) { -                                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, -                                        "strdup failed"); -                        } else { -                                op_ret = libgf_client_path_lookup (&loc, handle, -                                                                   0); -                                if (op_ret == -1) { -                                        res = NULL; -                                } -                        } -                } -        } - -        return res; -} - -int32_t -libgf_client_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                           int32_t op_ret, int32_t op_errno, -                           struct iatt *prebuf, struct iatt *postbuf) -{ -        libgf_client_local_t *local = frame->local; - -        local->reply_stub = fop_truncate_cbk_stub (frame, NULL, op_ret, -                                                   op_errno, prebuf, postbuf); - -        LIBGF_REPLY_NOTIFY (local); -        return 0; -} - -int32_t  -libgf_client_truncate (libglusterfs_client_ctx_t *ctx,  -                       loc_t *loc, off_t length) -{ -        call_stub_t *stub = NULL; -        int32_t op_ret = 0; -        libgf_client_local_t *local = NULL; - -        LIBGF_CLIENT_FOP (ctx, stub, truncate, local, loc, length); -  -        op_ret = stub->args.truncate_cbk.op_ret; -        errno = stub->args.truncate_cbk.op_errno; - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path %s, status %d, errno %d", -                loc->path, op_ret, errno); - -        if (op_ret == -1) { -                goto out; -        } - -        libgf_transform_iattr (ctx, loc->inode, -                               &stub->args.truncate_cbk.postbuf); - -        libgf_update_iattr_cache (loc->inode, LIBGF_UPDATE_STAT, -                                  &stub->args.truncate_cbk.postbuf); -	call_stub_destroy (stub); - -out: -        return op_ret; -} - -int -glusterfs_glh_truncate (glusterfs_handle_t handle, const char *path, -                        off_t length) -{ -        int32_t op_ret = -1; -        loc_t loc = {0, }; -        libglusterfs_client_ctx_t *ctx = handle; -	char *name = NULL, *pathname = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); -        GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); - -        loc.path = strdup (path); -        if (!loc.path) { -                gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "strdup failed"); -                goto out; -        } - -	op_ret = libgf_client_path_lookup (&loc, ctx, 1); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", GF_LOG_ERROR, -			"path lookup failed for (%s)", loc.path); -		goto out; -	} - -	pathname = strdup (loc.path); -	name = basename (pathname); - -        op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name); -	if (op_ret == -1) { -		gf_log ("libglusterfsclient", -			GF_LOG_ERROR, -			"libgf_client_loc_fill returned -1, returning EINVAL"); -		errno = EINVAL; -		goto out; -	} - -        op_ret = libgf_client_truncate (ctx, &loc, length); - -out: -        libgf_client_loc_wipe (&loc); - -        return op_ret; -} - -int -glusterfs_truncate (const char *path, off_t length) -{ -        int                     op_ret = -1; -        char                    vpath[PATH_MAX]; -        glusterfs_handle_t      h = NULL; - -        GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); - -        gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "path:%s length:%"PRIu64, path, -                length); -        h = libgf_resolved_path_handle (path, vpath); -        if (!h) { -                errno = ENODEV; -                goto out; -        } - -        op_ret = glusterfs_glh_truncate (h, vpath, length); -out: -        return op_ret; -} - -static struct xlator_fops libgf_client_fops = { -}; - -static struct xlator_cbks libgf_client_cbks = { -        .forget      = libgf_client_forget, -	.release     = libgf_client_release, -	.releasedir  = libgf_client_releasedir, -}; - -static inline xlator_t * -libglusterfs_graph (xlator_t *graph) -{ -        int       ret = 0; -        xlator_t *top = NULL; -        xlator_list_t *xlchild, *xlparent; - -        top = CALLOC (1, sizeof (*top)); -        ERR_ABORT (top); - -        xlchild = CALLOC (1, sizeof(*xlchild)); -        ERR_ABORT (xlchild); -        xlchild->xlator = graph; -        top->children = xlchild; -        top->ctx = graph->ctx; -        top->next = graph; -        top->name = strdup (LIBGF_XL_NAME); - -        xlparent = CALLOC (1, sizeof(*xlparent)); -        xlparent->xlator = top; -        graph->parents = xlparent; -        ret = asprintf (&top->type, LIBGF_XL_NAME); -        if (-1 == ret) { -                fprintf (stderr, "failed to set the top xl's type"); -        } - -        top->init = libgf_client_init; -        top->fops = &libgf_client_fops; -        top->mops = &libgf_client_mops; -        top->cbks = &libgf_client_cbks;  -        top->notify = libgf_client_notify; -        top->fini = libgf_client_fini; -        //  fill_defaults (top); - -        return top; -} diff --git a/libglusterfsclient/src/libglusterfsclient.h b/libglusterfsclient/src/libglusterfsclient.h deleted file mode 100755 index 1691a2faad3..00000000000 --- a/libglusterfsclient/src/libglusterfsclient.h +++ /dev/null @@ -1,1363 +0,0 @@ -/* -  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> -  This file is part of GlusterFS. - -  This file is licensed to you under your choice of the GNU Lesser -  General Public License, version 3 or any later version (LGPLv3 or -  later), or the GNU General Public License, version 2 (GPLv2), in all -  cases as published by the Free Software Foundation. -*/ - -#ifndef _LIBGLUSTERFSCLIENT_H -#define _LIBGLUSTERFSCLIENT_H - -#ifndef __BEGIN_DECLS -#ifdef __cplusplus -#define __BEGIN_DECLS extern "C" { -#else -#define __BEGIN_DECLS -#endif -#endif - -#ifndef __END_DECLS -#ifdef __cplusplus -#define __END_DECLS } -#else -#define __END_DECLS -#endif -#endif - - -__BEGIN_DECLS - -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <sys/statfs.h> -#include <sys/statvfs.h> -#include <utime.h> -#include <sys/time.h> -#include <stdint.h> - -typedef struct { -        struct iovec *vector; -        int           count; -        void         *iobref; -        void         *dictref; -} glusterfs_iobuf_t; - - -typedef -int (*glusterfs_readv_cbk_t) (int op_ret, int op_errno, glusterfs_iobuf_t *buf, -			      void *cbk_data); - -typedef -int (*glusterfs_write_cbk_t) (int op_ret, int op_errno, void *cbk_data); - -typedef -int (*glusterfs_get_cbk_t) (int op_ret, int op_errno, glusterfs_iobuf_t *buf, -			    struct stat *stbuf, void *cbk_data); - - -/* Data Interface - * The first section describes the data structures required for - * using libglusterfsclient. - */ - -/* This structure needs to be filled up and - * passed to te glusterfs_init function which uses - * the params passed herein to initialize a glusterfs - * client context and then connect to a glusterfs server. - */ -typedef struct { -        char          *logfile;         /* Path to the file which will store -                                           the log. -                                           */ -        char          *loglevel;        /* The log level required for -                                           reporting various events within -                                           libglusterfsclient. -                                           */ -        struct { -                char  *specfile;        /* Users can either open a volume or -                                           specfile and assign the pointer to -                                           specfp, or just refer to the volume -                                           /spec file path in specfile. -                                           */ -                FILE  *specfp; -        }; -        char          *volume_name;     /* The volume file could describe many -                                           volumes but the specific volume -                                           within that file is chosen by -                                           specifying the volume name here. -                                           */ -        unsigned long  lookup_timeout;  /* libglusterclient provides the inode -                                           numbers to be cached by the library. -                                           The duration for which these are -                                           cached are defined by lookup_timeout -                                           . In Seconds. -                                           */ -        unsigned long  stat_timeout;    /* The file attributes received from -                                           a stat syscall can also be cached -                                           for the duration specified in this -                                           member. In Seconds. -                                           */ -} glusterfs_init_params_t; - - - -/* This is the handle returned by glusterfs_init - * once the initialization is complete. - * Users should treat this as an opaque handle. - */ -typedef void * glusterfs_handle_t; - - - -/* These identifiers are used as handles for files and dirs. - * Users of libglusterfsclient should not in anyway try to interpret - * the actual structures these will point to. - */ -typedef void * glusterfs_file_t; -typedef void * glusterfs_dir_t; - - -/* Function Call Interface */ -/* libglusterfsclient initialization function. - * @ctx : the structure described above filled with required values. - * @fakefsid: User generated fsid to be used to identify this - * volume. - * - * Returns NULL on failure and the non-NULL pointer on success. - * On failure, the error description might be present in the logfile - * depending on the log level. - */ -glusterfs_handle_t -glusterfs_init (glusterfs_init_params_t *ctx, uint32_t fakefsid); - - - -/* Used to destroy a glusterfs client context and the - * connection to the glusterfs server. - * - * @handle      : The glusterfs handle returned by glusterfs_init. - */ -int -glusterfs_fini (glusterfs_handle_t handle); - - - -/* libglusterfs client provides two interfaces. - * 1. handle-based interface - * Functions that comprise the handle-based interface accept the - * glusterfs_handle_t as the first argument. It specifies the - * glusterfs client context over which to perform the operation. - * - * 2. Virtual Mount Point based interface: - * Functions that do not require a handle to be given in order to - * identify which client context to operate on. This interface - * internally determines the corresponding client context for the - * given path. The down-side is that a virtual mount point (VMP) needs to be - * registered with the library. A VMP is just a string that maps to a - * glusterfs_handle_t. The advantage of a VMP based interface is that - * a user program using multiple client contexts does not need to - * maintain its own mapping between paths and the corresponding - * handles. - */ - - - -/* glusterfs_mount is the function that allows users to register a VMP - * along with the parameters, which will be used to initialize a - * context. Applications calling glusterfs_mount do not need to - * initialized a context using the glusterfs_init interface. - * - * @vmp         : The virtual mount point. - * @ipars       : Initialization parameters populated as described - *              earlier. - * - * Returns 0 on success, and -1 on failure. - */ -int -glusterfs_mount (char *vmp, glusterfs_init_params_t *ipars); - - - -/* glusterfs_umount is the VMP equivalent of glusterfs_fini. - * - * @vmp         : The VMP which was initialized using glusterfs_mount. - * - * Returns 0 on sucess, and -1 on failure. - */ -int -glusterfs_umount (char *vmp); - - -/* glusterfs_umount_all unmounts all the mounts */ -int -glusterfs_umount_all (void); - - -/* For smaller files, application can use just - * glusterfs_get/glusterfs_get_async - * to read the whole content. Limit of the file-sizes to be read in - * glusterfs_get/glusterfs_get_async is passed in the size argument - */ - -/* glusterfs_glh_get: - * @handle : glusterfs handle - * @path   : path to be looked upon - * @size   : upper limit of file-sizes to be read in lookup - * @stbuf  : attribute buffer - */ - -int -glusterfs_glh_get (glusterfs_handle_t handle, const char *path, void *buf, -	       size_t size, struct stat *stbuf); - -int -glusterfs_get (const char *path, void *buf, size_t size, struct stat *stbuf); - -int -glusterfs_get_async (glusterfs_handle_t handle, const char *path, size_t size, -		     glusterfs_get_cbk_t cbk, void *cbk_data); - - - -/* Opens a file. Corresponds to the open syscall. - * - * @handle      : Handle returned from glusterfs_init - * @path        : Path to the file or directory on the glusterfs - *              export. Must be absolute to the export on the server. - * @flags       : flags to control open behaviour. - * @...         : The mode_t argument that defines the mode for a new - *              file, in case a new file is being created using the - *              O_CREAT flag in @flags. - * - * Returns a non-NULL handle on success. NULL on failure and sets - * errno accordingly. - */ -glusterfs_file_t -glusterfs_glh_open (glusterfs_handle_t handle, const char *path, int flags, -                        ...); - - -/* Opens a file without having to specify a handle. - * - * @path        : Path to the file to open in the glusterfs export. - *              The path to the file in glusterfs export must be - *              pre-fixed with the VMP string registered with - *              glusterfs_mount. - * @flags       : flags to control open behaviour. - * @...         : The mode_t argument that defines the mode for a new - *              file, in case a new file is being created using the - *              O_CREAT flag in @flags. - * - * Returns 0 on success, -1 on failure with errno set accordingly. - */ -glusterfs_file_t -glusterfs_open (const char *path, int flags, ...); - - - -/* Creates a file. Corresponds to the creat syscall. - * - * @handle      : Handle returned from glusterfs_init - * @path        : Path to the file that needs to be created in the - *              glusterfs export. - * @mode        : File creation mode. - * - * Returns the file handle on success. NULL on error with errno set as - * required. - */ -glusterfs_file_t -glusterfs_glh_creat (glusterfs_handle_t handle, const char *path, mode_t mode); - - - -/* VMP-based creat. - * @path        : Path to the file to be created. Must be - *              pre-prepended with the VMP string registered with - *              glusterfs_mount. - * @mode        : File creation mode. - * - * Returns file handle on success. NULL handle on error with errno set - * accordingly. - */ -glusterfs_file_t -glusterfs_creat (const char *path, mode_t mode); - - - -/* Close the file identified by the handle. - * - * @fd          : Closes the file. - * - * Returns 0 on success, -1 on error with errno set accordingly. - */ -int -glusterfs_close (glusterfs_file_t fd); - - - -/* Get struct stat for the file in path. - * - * @handle      : The handle that identifies a glusterfs client - *              context. - * @path        : The file for which we need to get struct stat. - * @stbuf       : The buffer into which the file's stat is copied. - * - * Returns 0 on success and -1 on error with errno set accordingly. - */ -int -glusterfs_glh_stat (glusterfs_handle_t handle, const char *path, -                        struct stat *stbuf); - - -/* Get struct stat for file in path. - * - * @path        : The file for which struct stat is required. - * @sbuf        : The buffer into which the stat structure is copied. - * - * Returns 0 on success and -1 on error with errno set accordingly. - */ -int -glusterfs_stat (const char *path, struct stat *buf); - - - -/* Gets stat struct for the file. - * - * @handle      : The handle identifying a glusterfs client context. - * @path        : Path to the file for which stat structure is - *              required. If path is a symlink, the symlink is - *              interpreted and the stat structure returned for the - *              target of the link. - * @buf         : The buffer into which the stat structure is copied. - * - * Returns 0 on success and -1 on error with errno set accordingly. - */ -int -glusterfs_glh_lstat (glusterfs_handle_t handle, const char *path, -                        struct stat *buf); - - - -/* Gets stat struct for a file. - * - * @path        : The file to get the struct stat for. - * @buf         : The receiving struct stat buffer. - * - * Returns 0 on success and -1 on error with errno set accordingly. - */ -int -glusterfs_lstat (const char *path, struct stat *buf); - - - -/* Get stat structure for a file. - * - * @fd          : The file handle identifying a file on the glusterfs - *              server. - * @stbuf       : The buffer into which the stat data is copied. - * - * Returns 0 on success and -1 on error with errno set accordingly. - */ -int -glusterfs_fstat (glusterfs_file_t fd, struct stat *stbuf); - -int -glusterfs_glh_setxattr (glusterfs_handle_t handle, const char *path, -                                const char *name, const void *value, -                                size_t size, int flags); - -int -glusterfs_glh_lsetxattr (glusterfs_handle_t handle, const char *path, -                         const char *name, const void *value, size_t size, -                         int flags); - -int -glusterfs_setxattr (const char *path, const char *name, const void *value, -                        size_t size, int flags); - -int -glusterfs_lsetxattr (const char *path, const char *name, const void *value, -                     size_t size, int flags); - -int -glusterfs_fsetxattr (glusterfs_file_t fd, const char *name, const void *value, -                     size_t size, int flags); - -ssize_t -glusterfs_glh_getxattr (glusterfs_handle_t handle, const char *path, -		        const char *name, void *value, size_t size); - -ssize_t -glusterfs_glh_lgetxattr (glusterfs_handle_t handle, const char *path, -		         const char *name, void *value, size_t size); - -ssize_t -glusterfs_getxattr (const char *path, const char *name, void *value, -                        size_t size); - -ssize_t -glusterfs_lgetxattr (const char *path, const char *name, void *value, -                     size_t size); - -ssize_t -glusterfs_fgetxattr (glusterfs_file_t fd, const char *name, void *value, -		     size_t size); - -ssize_t -glusterfs_listxattr (glusterfs_handle_t handle, const char *path, char *list, -                     size_t size); - -ssize_t -glusterfs_llistxattr (glusterfs_handle_t handle, const char *path, char *list, -                      size_t size); - -ssize_t -glusterfs_flistxattr (glusterfs_file_t fd, char *list, size_t size); - -int -glusterfs_removexattr (glusterfs_handle_t handle, const char *path, -		       const char *name); - -int -glusterfs_lremovexattr (glusterfs_handle_t handle, const char *path, -			const char *name); - -int -glusterfs_fremovexattr (glusterfs_file_t fd, const char *name); - - - -/* Read data from a file. - * @fd          : Handle returned by glusterfs_open or - *              glusterfs_glh_open. - * @buf         : Buffer to read the data into. - * @nbytes      : Number of bytes to read. - * - * Returns number of bytes actually read on success or -1 on error - * with errno set to the appropriate error number. - */ -ssize_t -glusterfs_read (glusterfs_file_t fd, void *buf, size_t nbytes); - - - -/* Read data into an array of buffers. - * - * @fd          : File handle returned by glusterfs_open or - *              glusterfs_glh_open. - * @vec         : Array of buffers into which the data is read. - * @count       : Number of iovecs referred to by vec. - * - * Returns number of bytes read on success or -1 on error with errno - * set appropriately. - */ -ssize_t -glusterfs_readv (glusterfs_file_t fd, const struct iovec *vec, int count); - -int -glusterfs_read_async (glusterfs_file_t fd, size_t nbytes, off_t offset, -                      glusterfs_readv_cbk_t readv_cbk, void *cbk_data); - - - -/* Write data into a file. - * - * @fd          : File handle returned from glusterfs_open or - *              glusterfs_glh_open. - * @buf         : Buffer which is written to the file. - * @nbytes      : Number bytes of the @buf written to the file. - * - * On success, returns number of bytes written. On error, returns -1 - * with errno set appropriately. - */ -ssize_t -glusterfs_write (glusterfs_file_t fd, const void *buf, size_t nbytes); - - - -/* Writes an array of buffers into a file. - * - * @fd          : The file handle returned from glusterfs_open or - *              glusterfs_glh_open. - * @vector      : Array of buffers to be written to the file. - * @count       : Number of separate buffers in the @vector array. - * - * Returns number of bytes written on success or -1 on error with - * errno set approriately. - */ -ssize_t -glusterfs_writev (glusterfs_file_t fd, const struct iovec *vector, int count); - -int -glusterfs_write_async (glusterfs_file_t fd, const void *buf, size_t nbytes, -                       off_t offset, glusterfs_write_cbk_t write_cbk, -		       void *cbk_data); - -int -glusterfs_writev_async (glusterfs_file_t fd, const struct iovec *vector, -			int count, off_t offset, -			glusterfs_write_cbk_t write_cbk, void *cbk_data); - - - -/* Read from a file starting at a given offset. - * - * @fd          : File handle returned from glusterfs_open or - *              glusterfs_glh_open. - * @buf         : Buffer to read the data into. - * @nbytes      : Number of bytes to read. - * @offset      : The offset to start reading @nbytes from. - * - * Returns number of bytes read on success or -1 on error with errno - * set appropriately. - */ -ssize_t -glusterfs_pread (glusterfs_file_t fd, void *buf, size_t nbytes, off_t offset); - - - -/* Write to a file starting at a given offset. - * - * @fd          : Flie handle returned from glusterfs_open or - *              glusterfs_glh_open. - * @buf         : Buffer that will be written to the file. - * @nbytes      : Number of bytes to write from @buf. - * @offset      : The starting offset from where @nbytes will be - *              written. - * - * Returns number of bytes written on success and -1 on error with - * errno set appropriately. - */ -ssize_t -glusterfs_pwrite (glusterfs_file_t fd, const void *buf, size_t nbytes, -		  off_t offset); - - - -/* Seek to an offset in the file. - * - * @fd          : File handle in which to seek to. File handle - *              returned by glusterfs_open or glusterfs_glh_open. - * @offset      : Offset to seek to in the given file. - * @whence      : Determines how the offset is interpreted by this - *              syscall. The behaviour is similar to the options - *              provided by the POSIX lseek system call. See man lseek - *              for more details. - * - * On success, returns the resulting absolute offset in the file after the seek - * operation is performed. ON error, returns -1 with errno set - * appropriately. - */ -off_t -glusterfs_lseek (glusterfs_file_t fd, off_t offset, int whence); - - - -/* Create a directory. - * - * @handle      : The handle of the glusterfs context in which the - *              directory needs to be created. - * @path        : The absolute path within the glusterfs context where - *              the directory needs to be created. - * @mode        : The mode bits for the newly created directory. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_mkdir (glusterfs_handle_t handle, const char *path, mode_t mode); - - - -/* Create a directory. - * - * @path        : Path to the directory that needs to be created. This - *              path must be prefixed with the VMP of the particular glusterfs - *              context. - * @mode        : Mode flags for the newly created directory. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_mkdir (const char *path, mode_t mode); - - - -/* Remove a directory. - * - * @handle      : Handle of the glusterfs context from which to remove - *              the directory. - * @path        : The path of the directory to be removed in the glusterfs - *              context. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_rmdir (glusterfs_handle_t handle, const char *path); - - - -/* Remove a directory. - * - * @path        : The absolute path to the directory to be removed. - *              This path must be pre-fixed with the VMP of the - *              particular glusterfs context in which this directory - *              resides. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_rmdir (const char *path); - - - -/* Read directory entries. - * - * @fd          : The handle of the directory to be read. This handle - *              is the one returned by opendir. - * - * Returns the directory entry on success and NULL pointer on error - * with errno set appropriately. - */ -void * -glusterfs_readdir (glusterfs_dir_t dirfd); - - - -/* re-entrant version of glusterfs_readdir. - * - * @dirfd       : The handle of directory to be read. This handle is the one - *                returned by opendir. - * @entry       : Pointer to storage to store a directory entry. The storage - *                pointed to by entry shall be large enough for a dirent with  - *                an array of char d_name members containing at least - *                {NAME_MAX}+1 elements. - * @result      : Upon successful return, the pointer returned at *result shall - *                have the same value as the argument entry. Upon reaching the - *                end of the directory stream, this pointer shall have the - *                value NULL. - */ -int -glusterfs_readdir_r (glusterfs_dir_t dirfd, struct dirent *entry, -                     struct dirent **result); - -/* Close a directory handle. - * - * @fd          : The directory handle to be closed. - * - * Returns 0 on success and -1 on error with errno set to 0. - */ -int -glusterfs_closedir (glusterfs_dir_t dirfd); -/* FIXME: remove getdents */ -int -glusterfs_getdents (glusterfs_dir_t fd, struct dirent *dirp, -		    unsigned int count); - - - -/* Create device node. - * - * @handle      : glusterfs context in which to create the device - *              node. - * @pathname    : The absolute path of the device to be created in the - *              given glusterfs context. - * - * @mode        : Mode flags to apply to the newly created node. - * @dev         : Device numbers that will apply to the node. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_mknod(glusterfs_handle_t handle, const char *pathname, -                        mode_t mode, dev_t dev); - - - -/* Create a device node. - * - * @pathname    : The full path of the node to be created. This path - *              should be pre-pended with the VMP of the glusterfs - *              context in which this node is to be created. - * @mode        : Mode flags that will be applied to the newly created - *              device file. - * @dev         : The device numbers that will be associated with the - *              device node. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_mknod(const char *pathname, mode_t mode, dev_t dev); - - - -/* Returns the real absolute path of the given path. - * - * @handle              : The glusterfs context in which the path resides in. - * @path                : The path to be resolved. - * @resolved_path       : The resolved path is stored in this buffer - *                      provided by the caller. - * - * Returns a pointer to resolved_path on success and NULL on error - * with errno set appropriately. - * - * See man realpath for details. - */ -char * -glusterfs_glh_realpath (glusterfs_handle_t handle, const char *path, -                        char *resolved_path); - - -/* Returns the real absolute path of the given path. - * - * @path                : The path to be resolved. This path must be - *                      pre-fixed with the VMP of the glusterfs - *                      context in which the file resides. - * - * @resolved_path       : The resolved path is stored in this user - *                      provided buffer. - * - * Returns a pointer to resolved_path on success, and NULL on error - * with errno set appropriately. - */ -char * -glusterfs_realpath (const char *path, char *resolved_path); - - - -/* Change mode flags on a path. - * - * @handle      : Handle of the glusterfs instance in which the path - *              resides. - * @path        : The path whose mode bits need to be changed. - * @mode        : The new mode bits. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_chmod (glusterfs_handle_t handle, const char *path, mode_t mode); - - - -/* Change mode flags on a path. - * - * @path        : The path whose mode bits need to be changed. The - *              path should be pre-fixed with the VMP that identifies the - *              glusterfs context within which the path resides. - * @mode        : The new mode bits. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_chmod (const char *path, mode_t mode); - - - -/* Change the owner of a path. - * If @path is a symlink, it is dereferenced and the ownership change - * happens on the target. - * - * @handle      : Handle of the glusterfs context in which the path - *              resides. - * @path        : The path whose owner needs to be changed. - * @owner       : ID of the new owner. - * @group       : ID of the new group. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_chown (glusterfs_handle_t handle, const char *path, uid_t owner, -                        gid_t group); - - - -/* Change the owner of a path. - * - * If @path is a symlink, it is dereferenced and the ownership change - * happens on the target. - * @path        : The path whose owner needs to be changed. Path must - *              be pre-fixed with the VMP that identifies the - *              glusterfs context in which the path resides. - * @owner       : ID of the new owner. - * @group       : ID of the new group. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_chown (const char *path, uid_t owner, gid_t group); - - - -/* Change the owner of the file. - * - * @fd          : Handle of the file whose owner needs to be changed. - * @owner       : ID of the new owner. - * @group       : ID of the new group. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_fchown (glusterfs_file_t fd, uid_t owner, gid_t group); - - - -/* Open a directory. - * - * @handle      : Handle that identifies a glusterfs context. - * @path        : Path to the directory in the glusterfs context. - * - * Returns a non-NULL handle on success and NULL on failure with errno - * set appropriately. - */ -glusterfs_dir_t -glusterfs_glh_opendir (glusterfs_handle_t handle, const char *path); - - - -/* Open a directory. - * - * @path        : Path to the directory. The path must be prepended - *              with the VMP in order to identify the glusterfs - *              context in which path resides. - * - * Returns a non-NULL handle on success and NULL on failure with errno - * set appropriately. - */ -glusterfs_dir_t -glusterfs_opendir (const char *path); - - - -/* Change the mode bits on an open file. - * - * @fd          : The file whose mode bits need to be changed. - * @mode        : The new mode bits. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_fchmod (glusterfs_file_t fd, mode_t mode); - - - -/* Sync the file contents to storage. - * - * @fd          : The file whose contents need to be sync'ed to - *              storage. - * - * Return 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_fsync (glusterfs_file_t *fd); - - - -/* Truncate an open file. - * - * @fd          : The file to truncate. - * @length      : The length to truncate to. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_ftruncate (glusterfs_file_t fd, off_t length); - - - -/* Create a hard link between two paths. - * - * @handle      : glusterfs context in which both paths should reside. - * @oldpath     : The existing path to link to. - * @newpath     : The new path which will be linked to @oldpath. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_link (glusterfs_handle_t handle, const char *oldpath, -                        const char *newpath); - - - -/* Create a hard link between two paths. - * - * @oldpath     : The existing path to link to. - * @newpath     : The new path which will be linked to @oldpath. - * - * Both paths should exist on the same glusterfs context and should be - * prefixed with the same VMP. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_link (const char *oldpath, const char *newpath); - - - -/* Get stats about the underlying file system. - * - * @handle      : Identifies the glusterfs context in which resides - *              the given path. - * @path        : stats are returned for the file system on which file - *              is located. - * @buf         : The buffer into which the stats are copied. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_statfs (glusterfs_handle_t handle, const char *path, -                        struct statfs *buf); - - - -/* Get stats about the underlying file system. - * - * @path        : stats are returned for the file system on which file - *              is located. @path must start with the VMP of the - *              glusterfs context on which the file reside. - * @buf         : The buffer into which the stats are copied. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_statfs (const char *path, struct statfs *buf); - - - -/* Get stats about the underlying file system. - * - * @handle      : Identifies the glusterfs context in which resides - *              the given path. - * @path        : stats are returned for the file system on which file - *              is located. - * @buf         : The buffer into which the stats are copied. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_statvfs (glusterfs_handle_t handle, const char *path, -                   struct statvfs *buf); - - - -/* Get stats about the underlying file system. - * - * @path        : stats are returned for the file system on which file - *              is located. @path must start with the VMP of the - *              glusterfs context on which the file reside. - * @buf         : The buffer into which the stats are copied. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_statvfs (const char *path, struct statvfs *buf); - - - -/* Set the atime and mtime values for a given path. - * - * @handle      : The handle identifying the glusterfs context. - * @path        : The path for which the times need to be changed. - * @times       : The array containing new time stamps for the file. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_utimes (glusterfs_handle_t handle, const char *path, -                        const struct timeval times[2]); - - - -/* Set the atime and mtime values for a given path. - * - * @path        : The path for which the times need to be changed. - * @times       : The array containing new time stamps for the file. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_utimes (const char *path, const struct timeval times[2]); - - - -/* Set the atime and mtime values for a given path. - * - * @handle      : The handle identifying the glusterfs context. - * @path        : The path for which the times need to be changed. - * @buf         : The structure containing new time stamps for the file. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_utime (glusterfs_handle_t handle, const char *path, -                        const struct utimbuf *buf); - - - -/* Set the atime and mtime values for a given path. - * - * @path        : The path for which the times need to be changed. - * @buf         : The structure containing new time stamps for the file. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_utime (const char *path, const struct utimbuf *buf); - - - -/*  Create  FIFO at the given path. - * - *  @handle     : The glusterfs context in which to create that FIFO. - *  @path       : The path within the context where the FIFO is to be - *              created. - * @mode        : The mode bits for the newly create FIFO. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_mkfifo (glusterfs_handle_t handle, const char *path, -                        mode_t mode); - - - -/*  Create  FIFO at the given path. - * - *  @path       : The path within the context where the FIFO is to be - *              created. @path should begin with the VMP of the - *              glusterfs context in which the FIFO needs to be - *              created. - * @mode        : The mode bits for the newly create FIFO. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_mkfifo (const char *path, mode_t mode); - - - -/* Unlink a file. - * - * @handle      : Handle that identifies a glusterfs instance. - * @path        : Path in the glusterfs instance that needs to be - *              unlinked. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_unlink (glusterfs_handle_t handle, const char *path); - - - -/* Unlink a file. - * - * @path        : Path in the glusterfs instance that needs to be - *              unlinked. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_unlink (const char *path); - - - -/* Create a symbolic link. - * - * @handle      : The handle identifying the glusterfs context. - * @oldpath     : The existing path to which a symlink needs to be - *              created. - * @newpath     : The new path which will be symlinked to the - *              @oldpath. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_symlink (glusterfs_handle_t handle, const char *oldpath, -                                const char *newpath); - - - -/* Create a symbolic link. - * - * @oldpath     : The existing path to which a symlink needs to be - *              created. - * @newpath     : The new path which will be symlinked to the - *              @oldpath. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_symlink (const char *oldpath, const char *newpath); - - - -/* Read a symbolic link. - * - * @handle      : Handle identifying the glusterfs context. - * @path        : The symlink that needs to be read. - * @buf         : The buffer into which the target of @path will be - *              stored. - * @bufsize     : Size of the buffer allocated to @buf. - * - * Returns number of bytes copied into @buf and -1 on error with errno - * set appropriately. - */ -ssize_t -glusterfs_glh_readlink (glusterfs_handle_t handle, const char *path, char *buf, -                                size_t bufsize); - - - -/* Read a symbolic link. - * - * @path        : The symlink that needs to be read. - * @buf         : The buffer into which the target of @path will be - *              stored. - * @bufsize     : Size of the buffer allocated to @buf. - * - * Returns number of bytes copied into @buf and -1 on error with errno - * set appropriately. - */ -ssize_t -glusterfs_readlink (const char *path, char *buf, size_t bufsize); - - - -/* Rename a file or directory. - * - * @handle      : The identifier of a glusterfs context. - * @oldpath     : The path to be renamed. - * @newpath     : The new name for the @oldpath. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_rename (glusterfs_handle_t handle, const char *oldpath, -                      const char *newpath); - - - -/* Rename a file or directory. - * @oldpath     : The path to be renamed. - * @newpath     : The new name for the @oldpath. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_rename (const char *oldpath, const char *newpath); - - - -/* Remove a file or directory in the given glusterfs context. - * - * @handle      : Handle identifying the glusterfs context. - * @path        : Path of the file or directory to be removed. - * - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_remove (glusterfs_handle_t handle, const char *path); - - - -/* Remove a file or directory. - * - * @path        : Path of the file or directory to be removed. The - *              path must be pre-fixed with the VMP. - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_remove (const char *path); - - - -/* Change the owner of the given path. - * - * If @path is a symlink, the ownership change happens on the symlink. - * - * @handle      : Handle identifying the glusterfs client context. - * @path        : Path whose owner needs to be changed. - * @owner       : New owner ID - * @group       : New Group ID - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ -int -glusterfs_glh_lchown (glusterfs_handle_t handle, const char *path, uid_t owner, -                      gid_t group); - - - -/* Change the owner of the given path. - * - * If @path is a symlink, the ownership change happens on the symlink. - * - * @path        : Path whose owner needs to be changed. - * @owner       : New owner ID - * @group       : New Group ID - * - * Returns 0 on success and -1 on error with errno set appropriately. - */ - -int -glusterfs_lchown (const char *path, uid_t owner, gid_t group); - - - -/* Rewind directory stream pointer to beginning of the directory. - * - * @dirfd       : Directory handle returned by glusterfs_open on - *              glusterfs_opendir. - * - * Returns no value. - */ -void -glusterfs_rewinddir (glusterfs_dir_t dirfd); - - - -/* Seek to the given offset in the directory handle. - * - * @dirfd       : Directory handle returned by glusterfs_open on - *              glusterfs_opendir. - * @offset      : The offset to seek to. - * - * Returns no value. - */ -void -glusterfs_seekdir (glusterfs_dir_t dirfd, off_t offset); - - - -/* Return the current offset in a directory stream. - * - * @dirfd       : Directory handle returned by glusterfs_open on - *              glusterfs_opendir. - * - * Returns the offset in the directory or -1 on error with errno set - * appropriately. - */ -off_t -glusterfs_telldir (glusterfs_dir_t dirfd); - - -/* Write count bytes from in_fd to out_fd, starting at *offset. - * glusterfs_sendfile aims at eliminating memory copy at the end of - * each read from in_fd, copying the file directly to out_fd from the buffer  - * provided by glusterfs. - * - * @out_fd: file descriptor opened for writing - * - * @in_fd: glusterfs file handle to the file to be read from. - * - * @offset: If offset is not NULL, then it points to a variable holding the file - *          offset  from  which  glusterfs_sendfile()  will  start reading data - *          from in_fd.  When glusterfs_sendfile() returns, this variable will  - *          be set to the offset of the byte following the last byte that was  - *          read.  If offset is  not  NULL, then glusterfs_sendfile()  does  not - *          modify the current file offset of in_fd; otherwise the current file - *          offset is adjusted to reflect the number of bytes read from in_fd. - * - * @count:  number of bytes to copy between the file descriptors. - */ - -ssize_t -glusterfs_sendfile (int out_fd, glusterfs_file_t in_fd, off_t *offset, -                    size_t count); - -/* manipulate file descriptor - * This api can have 3 forms similar to fcntl(2). - * - * int - * glusterfs_fcntl (glusterfs_file_t fd, int cmd) - * - * int - * glusterfs_fcntl (glusterfs_file_t fd, int cmd, long arg) - * - * int - * glusterfs_fcntl (glusterfs_file_t fd, int cmd, struct flock *lock) - * - * @fd   : file handle returned by glusterfs_open or glusterfs_create. - * @cmd  : Though the aim is to implement all possible commands supported by - *         fcntl(2), currently following commands are supported. - *         F_SETLK, F_SETLKW, F_GETLK -  used to acquire, release, and test for - *                                       the existence of record locks (also  - *                                       known as file-segment or file-region - *                                       locks). More detailed explanation is - *                                       found in 'man 2 fcntl' - */ -    -int -glusterfs_fcntl (glusterfs_file_t fd, int cmd, ...); - -/* - * Change the current working directory to @path - *  - * @path  : path to change the current working directory to. - * - * Returns 0 on success and -1 on failure with errno set appropriately. - */ -int -glusterfs_chdir (const char *path); - -/* - * Change the current working directory to the path @fd is opened on. - * - * @fd   : current working directory will be changed to path @fd is opened on. - * - * Returns 0 on success and -1 on  with errno set appropriately. - */ -int -glusterfs_fchdir (glusterfs_file_t fd); - -/* copies the current working directory into @buf if it is big enough - * - * @buf: buffer to copy into it. If @buf is NULL, a buffer will be allocated. - *       The size of the buffer will be @size if it is not zero, otherwise the - *       size will be big enough to hold the current working directory. - * @size: size of the buffer. - * - * Returns the pointer to buffer holding current working directory on success - * and NULL on failure. - */ - -char * -glusterfs_getcwd (char *buf, size_t size); - -/* - * Truncate the file to a specified length. - * - * @path   : path to the file. - * @length : length to which the file has to be truncated. - * - * Returns 0 on success and -1 on failure with errno set appropriately  - */ - -int -glusterfs_truncate (const char *path, off_t length); - - -/* FIXME: review the need for these apis */ -/* added for log related initialization in booster fork implementation */ -void -glusterfs_reset (void); - -void -glusterfs_log_lock (void); - -void -glusterfs_log_unlock (void); -/* Used to free the glusterfs_read_buf passed to the application from -   glusterfs_read_async_cbk -*/ -void -glusterfs_free (glusterfs_iobuf_t *buf); - -__END_DECLS - -#endif /* !_LIBGLUSTERFSCLIENT_H */ diff --git a/scheduler/Makefile.am b/scheduler/Makefile.am deleted file mode 100644 index 618fa7dd8b8..00000000000 --- a/scheduler/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = alu random nufa rr switch - -CLEANFILES =  diff --git a/scheduler/alu/Makefile.am b/scheduler/alu/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/scheduler/alu/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/scheduler/alu/src/Makefile.am b/scheduler/alu/src/Makefile.am deleted file mode 100644 index eb7d0db07e0..00000000000 --- a/scheduler/alu/src/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -sched_LTLIBRARIES = alu.la -scheddir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler - -alu_la_LDFLAGS = -module -avoidversion - -alu_la_SOURCES = alu.c -alu_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -noinst_HEADERS = alu.h - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) - -CLEANFILES =  diff --git a/scheduler/alu/src/alu-mem-types.h b/scheduler/alu/src/alu-mem-types.h deleted file mode 100644 index 92702f28690..00000000000 --- a/scheduler/alu/src/alu-mem-types.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -   Copyright (c) 2008-2011 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/>. -*/ - - -#ifndef __ALU_MEM_TYPES_H__ -#define __ALU_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_alu_mem_types_ { -        gf_alu_mt_alu_threshold = gf_common_mt_end + 1, -        gf_alu_mt_alu_sched, -        gf_alu_mt_alu_limits, -        gf_alu_mt_alu_sched_struct, -        gf_alu_mt_alu_sched_node, -        gf_alu_mt_end -}; -#endif - diff --git a/scheduler/alu/src/alu.c b/scheduler/alu/src/alu.c deleted file mode 100644 index 58bef60ae9f..00000000000 --- a/scheduler/alu/src/alu.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* -  Copyright (c) 2006-2011 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/>. -*/ - - - -/* ALU code needs a complete re-write. This is one of the most important  - * part of GlusterFS and so needs more and more reviews and testing  - */ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <sys/time.h> -#include <stdint.h> -#include "stack.h" -#include "alu.h" -#include "alu-mem-types.h" - -#define ALU_DISK_USAGE_ENTRY_THRESHOLD_DEFAULT         (1 * GF_UNIT_GB) -#define ALU_DISK_USAGE_EXIT_THRESHOLD_DEFAULT          (512 * GF_UNIT_MB) - -#define ALU_WRITE_USAGE_ENTRY_THRESHOLD_DEFAULT        25 -#define ALU_WRITE_USAGE_EXIT_THRESHOLD_DEFAULT         5 - -#define ALU_READ_USAGE_ENTRY_THRESHOLD_DEFAULT         25 -#define ALU_READ_USAGE_EXIT_THRESHOLD_DEFAULT          5 - -#define ALU_OPEN_FILES_USAGE_ENTRY_THRESHOLD_DEFAULT   1000 -#define ALU_OPEN_FILES_USAGE_EXIT_THRESHOLD_DEFAULT    100 - -#define ALU_LIMITS_TOTAL_DISK_SIZE_DEFAULT             100 - -#define ALU_REFRESH_INTERVAL_DEFAULT                   5 -#define ALU_REFRESH_CREATE_COUNT_DEFAULT               5 - - -static int64_t  -get_stats_disk_usage (struct xlator_stats *this) -{ -	return this->disk_usage; -} - -static int64_t  -get_stats_write_usage (struct xlator_stats *this) -{ -	return this->write_usage; -} - -static int64_t  -get_stats_read_usage (struct xlator_stats *this) -{ -	return this->read_usage; -} - -static int64_t  -get_stats_disk_speed (struct xlator_stats *this) -{ -	return this->disk_speed; -} - -static int64_t  -get_stats_file_usage (struct xlator_stats *this) -{ -	/* Avoid warning "defined but not used" */ -	(void) &get_stats_file_usage;     - -	return this->nr_files; -} - -static int64_t  -get_stats_free_disk (struct xlator_stats *this) -{ -	if (this->total_disk_size > 0) -		return (this->free_disk * 100) / this->total_disk_size; -	return 0; -} - -static int64_t  -get_max_diff_write_usage (struct xlator_stats *max, struct xlator_stats *min) -{ -	return (max->write_usage - min->write_usage); -} - -static int64_t  -get_max_diff_read_usage (struct xlator_stats *max, struct xlator_stats *min) -{ -	return (max->read_usage - min->read_usage); -} - -static int64_t  -get_max_diff_disk_usage (struct xlator_stats *max, struct xlator_stats *min) -{ -	return (max->disk_usage - min->disk_usage); -} - -static int64_t  -get_max_diff_disk_speed (struct xlator_stats *max, struct xlator_stats *min) -{ -	return (max->disk_speed - min->disk_speed); -} - -static int64_t  -get_max_diff_file_usage (struct xlator_stats *max, struct xlator_stats *min) -{ -	return (max->nr_files - min->nr_files); -} - - -int  -alu_parse_options (xlator_t *xl, struct alu_sched *alu_sched) -{ -	data_t *order = dict_get (xl->options, "scheduler.alu.order"); -	if (!order) { -		gf_log (xl->name, GF_LOG_ERROR, -			"option 'scheduler.alu.order' not specified"); -		return -1; -	} -	struct alu_threshold *_threshold_fn; -	struct alu_threshold *tmp_threshold; -	data_t *entry_fn = NULL; -	data_t *exit_fn = NULL; -	char *tmp_str = NULL; -	char *order_str = strtok_r (order->data, ":", &tmp_str); -	/* Get the scheduling priority order, specified by the user. */ -	while (order_str) { -		gf_log ("alu", GF_LOG_DEBUG, -			"alu_init: order string: %s", -			order_str); -		if (strcmp (order_str, "disk-usage") == 0) { -			/* Disk usage */ -			_threshold_fn =  -				GF_CALLOC (1, -                                           sizeof (struct alu_threshold), -                                           gf_alu_mt_alu_threshold); -			ERR_ABORT (_threshold_fn); -			_threshold_fn->diff_value = get_max_diff_disk_usage; -			_threshold_fn->sched_value = get_stats_disk_usage; -			entry_fn =  -				dict_get (xl->options,  -					  "scheduler.alu.disk-usage.entry-threshold"); -			if (entry_fn) { -				if (gf_string2bytesize (entry_fn->data,  -							&alu_sched->entry_limit.disk_usage) != 0) { -					gf_log (xl->name, GF_LOG_ERROR,  -						"invalid number format \"%s\" " -						"of \"option scheduler.alu." -						"disk-usage.entry-threshold\"", -						entry_fn->data); -					return -1; -				} -			} else { -				alu_sched->entry_limit.disk_usage = ALU_DISK_USAGE_ENTRY_THRESHOLD_DEFAULT; -			} -			_threshold_fn->entry_value = get_stats_disk_usage; -			exit_fn = dict_get (xl->options,  -					    "scheduler.alu.disk-usage.exit-threshold"); -			if (exit_fn) { -				if (gf_string2bytesize (exit_fn->data, &alu_sched->exit_limit.disk_usage) != 0)	{ -					gf_log (xl->name, GF_LOG_ERROR,  -						"invalid number format \"%s\" " -						"of \"option scheduler.alu." -						"disk-usage.exit-threshold\"",  -						exit_fn->data); -					return -1; -				} -			} else { -				alu_sched->exit_limit.disk_usage = ALU_DISK_USAGE_EXIT_THRESHOLD_DEFAULT; -			} -			_threshold_fn->exit_value = get_stats_disk_usage; -			tmp_threshold = alu_sched->threshold_fn; -			if (!tmp_threshold) { -				alu_sched->threshold_fn = _threshold_fn; -			} else { -				while (tmp_threshold->next) { -					tmp_threshold = tmp_threshold->next; -				} -				tmp_threshold->next = _threshold_fn; -			} -			gf_log ("alu", -				GF_LOG_DEBUG, "alu_init: = %"PRId64",%"PRId64"",  -				alu_sched->entry_limit.disk_usage,  -				alu_sched->exit_limit.disk_usage); -			 -		} else if (strcmp (order_str, "write-usage") == 0) { -			/* Handle "write-usage" */ -			 -			_threshold_fn = GF_CALLOC (1, sizeof (struct alu_threshold), gf_alu_mt_alu_threshold); -			ERR_ABORT (_threshold_fn); -			_threshold_fn->diff_value = get_max_diff_write_usage; -			_threshold_fn->sched_value = get_stats_write_usage; -			entry_fn = dict_get (xl->options,  -					     "scheduler.alu.write-usage.entry-threshold"); -			if (entry_fn) { -				if (gf_string2bytesize (entry_fn->data,  -							&alu_sched->entry_limit.write_usage) != 0) { -					gf_log (xl->name, GF_LOG_ERROR,  -						"invalid number format \"%s\" " -						"of option scheduler.alu." -						"write-usage.entry-threshold",  -						entry_fn->data); -					return -1; -				} -			} else { -				alu_sched->entry_limit.write_usage = ALU_WRITE_USAGE_ENTRY_THRESHOLD_DEFAULT; -			} -			_threshold_fn->entry_value = get_stats_write_usage; -			exit_fn = dict_get (xl->options,  -					    "scheduler.alu.write-usage.exit-threshold"); -			if (exit_fn) { -				if (gf_string2bytesize (exit_fn->data,  -							&alu_sched->exit_limit.write_usage) != 0) { -					gf_log (xl->name, GF_LOG_ERROR,  -						"invalid number format \"%s\"" -						" of \"option scheduler.alu." -						"write-usage.exit-threshold\"", -						exit_fn->data); -					return -1; -				} -			} else { -				alu_sched->exit_limit.write_usage = ALU_WRITE_USAGE_EXIT_THRESHOLD_DEFAULT; -			} -			_threshold_fn->exit_value = get_stats_write_usage; -			tmp_threshold = alu_sched->threshold_fn; -			if (!tmp_threshold) { -				alu_sched->threshold_fn = _threshold_fn; -			} else { -				while (tmp_threshold->next) { -					tmp_threshold = tmp_threshold->next; -				} -				tmp_threshold->next = _threshold_fn; -			} -			gf_log (xl->name, GF_LOG_DEBUG,  -				"alu_init: = %"PRId64",%"PRId64"",  -				alu_sched->entry_limit.write_usage,  -				alu_sched->exit_limit.write_usage); -			 -		} else if (strcmp (order_str, "read-usage") == 0) { -			/* Read usage */ -			 -			_threshold_fn = GF_CALLOC (1, sizeof (struct alu_threshold), gf_alu_mt_alu_threshold); -			ERR_ABORT (_threshold_fn); -			_threshold_fn->diff_value = get_max_diff_read_usage; -			_threshold_fn->sched_value = get_stats_read_usage; -			entry_fn = dict_get (xl->options,  -					     "scheduler.alu.read-usage.entry-threshold"); -			if (entry_fn) { -				if (gf_string2bytesize (entry_fn->data,  -							&alu_sched->entry_limit.read_usage) != 0) { -					gf_log (xl->name,  -						GF_LOG_ERROR,  -						"invalid number format \"%s\" " -						"of \"option scheduler.alu." -						"read-usage.entry-threshold\"", -						entry_fn->data); -					return -1; -				} -			} else { -				alu_sched->entry_limit.read_usage = ALU_READ_USAGE_ENTRY_THRESHOLD_DEFAULT; -			} -			_threshold_fn->entry_value = get_stats_read_usage; -			exit_fn = dict_get (xl->options,  -					    "scheduler.alu.read-usage.exit-threshold"); -			if (exit_fn) -			{ -				if (gf_string2bytesize (exit_fn->data,  -							&alu_sched->exit_limit.read_usage) != 0) -				{ -					gf_log ("alu", GF_LOG_ERROR,  -						"invalid number format \"%s\" " -						"of \"option scheduler.alu." -						"read-usage.exit-threshold\"",  -						exit_fn->data); -					return -1; -				} -			} -			else -			{ -				alu_sched->exit_limit.read_usage = ALU_READ_USAGE_EXIT_THRESHOLD_DEFAULT; -			} -			_threshold_fn->exit_value = get_stats_read_usage; -			tmp_threshold = alu_sched->threshold_fn; -			if (!tmp_threshold) { -				alu_sched->threshold_fn = _threshold_fn; -			} -			else { -				while (tmp_threshold->next) { -					tmp_threshold = tmp_threshold->next; -				} -				tmp_threshold->next = _threshold_fn; -			} -			gf_log ("alu", GF_LOG_DEBUG,  -				"alu_init: = %"PRId64",%"PRId64"",  -				alu_sched->entry_limit.read_usage,  -				alu_sched->exit_limit.read_usage); -			 -		} else if (strcmp (order_str, "open-files-usage") == 0) { -			/* Open files counter */ -			 -			_threshold_fn = GF_CALLOC (1, sizeof (struct alu_threshold), gf_alu_mt_alu_threshold); -			ERR_ABORT (_threshold_fn); -			_threshold_fn->diff_value = get_max_diff_file_usage; -			_threshold_fn->sched_value = get_stats_file_usage; -			entry_fn = dict_get (xl->options,  -					     "scheduler.alu.open-files-usage.entry-threshold"); -			if (entry_fn) { -				if (gf_string2uint64 (entry_fn->data,  -						      &alu_sched->entry_limit.nr_files) != 0) -				{ -					gf_log ("alu", GF_LOG_ERROR,  -						"invalid number format \"%s\" " -						"of \"option scheduler.alu." -						"open-files-usage.entry-" -						"threshold\"", entry_fn->data); -					return -1; -				} -			} -			else -			{ -				alu_sched->entry_limit.nr_files = ALU_OPEN_FILES_USAGE_ENTRY_THRESHOLD_DEFAULT; -			} -			_threshold_fn->entry_value = get_stats_file_usage; -			exit_fn = dict_get (xl->options,  -					    "scheduler.alu.open-files-usage.exit-threshold"); -			if (exit_fn) -			{ -				if (gf_string2uint64 (exit_fn->data,  -						      &alu_sched->exit_limit.nr_files) != 0) -				{ -					gf_log ("alu", GF_LOG_ERROR,  -						"invalid number format \"%s\" " -						"of \"option scheduler.alu." -						"open-files-usage.exit-" -						"threshold\"", exit_fn->data); -					return -1; -				} -			} -			else -			{ -				alu_sched->exit_limit.nr_files = ALU_OPEN_FILES_USAGE_EXIT_THRESHOLD_DEFAULT; -			} -			_threshold_fn->exit_value = get_stats_file_usage; -			tmp_threshold = alu_sched->threshold_fn; -			if (!tmp_threshold) { -				alu_sched->threshold_fn = _threshold_fn; -			} -			else { -				while (tmp_threshold->next) { -					tmp_threshold = tmp_threshold->next; -				} -				tmp_threshold->next = _threshold_fn; -			} -			gf_log ("alu", GF_LOG_DEBUG,  -				"alu.c->alu_init: = %"PRIu64",%"PRIu64"",  -				alu_sched->entry_limit.nr_files,  -				alu_sched->exit_limit.nr_files); -			 -		} else if (strcmp (order_str, "disk-speed-usage") == 0) { -			/* Disk speed */ -			 -			_threshold_fn = GF_CALLOC (1, sizeof (struct alu_threshold), gf_alu_mt_alu_threshold); -			ERR_ABORT (_threshold_fn); -			_threshold_fn->diff_value = get_max_diff_disk_speed; -			_threshold_fn->sched_value = get_stats_disk_speed; -			entry_fn = dict_get (xl->options,  -					     "scheduler.alu.disk-speed-usage.entry-threshold"); -			if (entry_fn) { -				gf_log ("alu", GF_LOG_DEBUG, -					"entry-threshold is given, " -					"value is constant"); -			} -			_threshold_fn->entry_value = NULL; -			exit_fn = dict_get (xl->options,  -					    "scheduler.alu.disk-speed-usage.exit-threshold"); -			if (exit_fn) { -				gf_log ("alu", GF_LOG_DEBUG, -					"exit-threshold is given, " -					"value is constant"); -			} -			_threshold_fn->exit_value = NULL; -			tmp_threshold = alu_sched->threshold_fn; -			if (!tmp_threshold) { -				alu_sched->threshold_fn = _threshold_fn; -			} -			else { -				while (tmp_threshold->next) { -					tmp_threshold = tmp_threshold->next; -				} -				tmp_threshold->next = _threshold_fn; -			} -			 -		} else { -			gf_log ("alu", GF_LOG_DEBUG, -				"%s, unknown option provided to scheduler", -				order_str); -		} -		order_str = strtok_r (NULL, ":", &tmp_str); -	} -	 -	return 0; -} - -static int32_t -alu_init (xlator_t *xl) -{ -	struct alu_sched *alu_sched = NULL; -	struct alu_limits *_limit_fn = NULL; -	struct alu_limits *tmp_limits = NULL; -	uint32_t min_free_disk = 0; -	data_t *limits = NULL; -   -	alu_sched = GF_CALLOC (1, sizeof (struct alu_sched), -                               gf_alu_mt_alu_sched); -	ERR_ABORT (alu_sched); - -	{ -		alu_parse_options (xl, alu_sched); -	} - -	/* Get the limits */ -	 -	limits = dict_get (xl->options,  -			   "scheduler.limits.min-free-disk"); -	if (limits) { -		_limit_fn = GF_CALLOC (1, sizeof (struct alu_limits), -                                       gf_alu_mt_alu_limits); -		ERR_ABORT (_limit_fn); -		_limit_fn->min_value = get_stats_free_disk; -		_limit_fn->cur_value = get_stats_free_disk; -		tmp_limits = alu_sched->limits_fn ; -		_limit_fn->next = tmp_limits; -		alu_sched->limits_fn = _limit_fn; -		 -		if (gf_string2percent (limits->data,  -				       &min_free_disk) != 0) { -			gf_log ("alu", GF_LOG_ERROR,  -				"invalid number format \"%s\" " -				"of \"option scheduler.limits." -				"min-free-disk\"", limits->data); -			return -1; -		} -		alu_sched->spec_limit.free_disk = min_free_disk; -		 -		if (alu_sched->spec_limit.free_disk >= 100) { -			gf_log ("alu", GF_LOG_ERROR, -				"check the \"option scheduler." -				"limits.min-free-disk\", it should " -				"be percentage value"); -			return -1; -		} -		alu_sched->spec_limit.total_disk_size = ALU_LIMITS_TOTAL_DISK_SIZE_DEFAULT; /* Its in % */ -		gf_log ("alu", GF_LOG_DEBUG, -			"alu.limit.min-disk-free = %"PRId64"",  -			_limit_fn->cur_value (&(alu_sched->spec_limit))); -	} -	 -	limits = dict_get (xl->options,  -			   "scheduler.limits.max-open-files"); -	if (limits) { -		// Update alu_sched->priority properly -		_limit_fn = GF_CALLOC (1, sizeof (struct alu_limits), -                                       gf_alu_mt_alu_limits); -		ERR_ABORT (_limit_fn); -		_limit_fn->max_value = get_stats_file_usage; -		_limit_fn->cur_value = get_stats_file_usage; -		tmp_limits = alu_sched->limits_fn ; -		_limit_fn->next = tmp_limits; -		alu_sched->limits_fn = _limit_fn; -		if (gf_string2uint64_base10 (limits->data,  -					     &alu_sched->spec_limit.nr_files) != 0) -		{ -			gf_log ("alu", GF_LOG_ERROR,  -				"invalid number format '%s' of option " -				"scheduler.limits.max-open-files",  -				limits->data); -			return -1; -		} -		 -		gf_log ("alu", GF_LOG_DEBUG, -			"alu_init: limit.max-open-files = %"PRId64"", -			_limit_fn->cur_value (&(alu_sched->spec_limit))); -	} - - -	/* Stats refresh options */ -	limits = dict_get (xl->options,  -			   "scheduler.refresh-interval"); -	if (limits) { -		if (gf_string2time (limits->data,  -				    &alu_sched->refresh_interval) != 0)	{ -			gf_log ("alu", GF_LOG_ERROR,  -				"invalid number format \"%s\" of " -				"option scheduler.refresh-interval",  -				limits->data); -			return -1; -		} -	} else { -		alu_sched->refresh_interval = ALU_REFRESH_INTERVAL_DEFAULT; -	} -	gettimeofday (&(alu_sched->last_stat_fetch), NULL); -	 -	 -	limits = dict_get (xl->options,  -			   "scheduler.alu.stat-refresh.num-file-create"); -	if (limits) { -		if (gf_string2uint32 (limits->data,  -				      &alu_sched->refresh_create_count) != 0) -		{ -			gf_log ("alu", GF_LOG_ERROR,  -				"invalid number format \"%s\" of \"option " -				"alu.stat-refresh.num-file-create\"",  -				limits->data); -			return -1; -		} -	} else { -		alu_sched->refresh_create_count = ALU_REFRESH_CREATE_COUNT_DEFAULT; -	} - -	{ -		/* Build an array of child_nodes */ -		struct alu_sched_struct *sched_array = NULL; -		xlator_list_t *trav_xl = xl->children; -		data_t *data = NULL; -		int32_t index = 0; -		 -		while (trav_xl) { -			index++; -			trav_xl = trav_xl->next; -		} -		alu_sched->child_count = index; -		sched_array = GF_CALLOC (index, sizeof (struct alu_sched_struct), gf_alu_mt_alu_sched_struct); -		ERR_ABORT (sched_array); -		trav_xl = xl->children; -		index = 0; -		while (trav_xl) { -			sched_array[index].xl = trav_xl->xlator; -			sched_array[index].eligible = 1; -			index++; -			trav_xl = trav_xl->next; -		} -		alu_sched->array = sched_array; - -		data = dict_get (xl->options,  -				 "scheduler.read-only-subvolumes"); -		if (data) { -			char *child = NULL; -			char *tmp = NULL; -			char *childs_data = gf_strdup (data->data); -       -			child = strtok_r (childs_data, ",", &tmp); -			while (child) { -				for (index = 1; index < alu_sched->child_count; index++) { -					if (strcmp (alu_sched->array[index -1].xl->name, child) == 0) { -						memcpy (&(alu_sched->array[index -1]),  -							&(alu_sched->array[alu_sched->child_count -1]),  -							sizeof (struct alu_sched_struct)); -						alu_sched->child_count--; -						break; -					} -				} -				child = strtok_r (NULL, ",", &tmp); -			} -		} -	} - -	*((long *)xl->private) = (long)alu_sched; - -	/* Initialize all the alu_sched structure's elements */ -	{ -		alu_sched->sched_nodes_pending = 0; - -		alu_sched->min_limit.free_disk = 0x00FFFFFF; -		alu_sched->min_limit.disk_usage = 0xFFFFFFFF; -		alu_sched->min_limit.total_disk_size = 0xFFFFFFFF; -		alu_sched->min_limit.disk_speed = 0xFFFFFFFF; -		alu_sched->min_limit.write_usage = 0xFFFFFFFF; -		alu_sched->min_limit.read_usage = 0xFFFFFFFF; -		alu_sched->min_limit.nr_files = 0xFFFFFFFF; -		alu_sched->min_limit.nr_clients = 0xFFFFFFFF; -	} - -	pthread_mutex_init (&alu_sched->alu_mutex, NULL); -	return 0; -} - -static void -alu_fini (xlator_t *xl) -{ -	if (!xl) -		return; -	struct alu_sched *alu_sched = (struct alu_sched *)*((long *)xl->private); -	struct alu_limits *limit = alu_sched->limits_fn; -	struct alu_threshold *threshold = alu_sched->threshold_fn; -	void *tmp = NULL; -	pthread_mutex_destroy (&alu_sched->alu_mutex); -	GF_FREE (alu_sched->array); -	while (limit) { -		tmp = limit; -		limit = limit->next; -		GF_FREE (tmp); -	} -	while (threshold) { -		tmp = threshold; -		threshold = threshold->next; -		GF_FREE (tmp); -	} -	GF_FREE (alu_sched); -} - -static int32_t  -update_stat_array_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *xl, -		       int32_t op_ret, -		       int32_t op_errno, -		       struct xlator_stats *trav_stats) -{ -	struct alu_sched *alu_sched = (struct alu_sched *)*((long *)xl->private); -	struct alu_limits *limits_fn = alu_sched->limits_fn; -	int32_t idx = 0; -   -	pthread_mutex_lock (&alu_sched->alu_mutex); -	for (idx = 0; idx < alu_sched->child_count; idx++) { -		if (alu_sched->array[idx].xl == (xlator_t *)cookie) -			break; -	} -	pthread_mutex_unlock (&alu_sched->alu_mutex); - -	if (op_ret == -1) { -		alu_sched->array[idx].eligible = 0; -	} else { -		memcpy (&(alu_sched->array[idx].stats), trav_stats, sizeof (struct xlator_stats)); -     -		/* Get stats from all the child node */ -		/* Here check the limits specified by the user to  -		   consider the nodes to be used by scheduler */ -		alu_sched->array[idx].eligible = 1; -		limits_fn = alu_sched->limits_fn; -		while (limits_fn){ -			if (limits_fn->max_value &&  -			    (limits_fn->cur_value (trav_stats) >  -			     limits_fn->max_value (&(alu_sched->spec_limit)))) { -				alu_sched->array[idx].eligible = 0; -			} -			if (limits_fn->min_value &&  -			    (limits_fn->cur_value (trav_stats) <  -			     limits_fn->min_value (&(alu_sched->spec_limit)))) { -				alu_sched->array[idx].eligible = 0; -			} -			limits_fn = limits_fn->next; -		} - -		/* Select minimum and maximum disk_usage */ -		if (trav_stats->disk_usage > alu_sched->max_limit.disk_usage) { -			alu_sched->max_limit.disk_usage = trav_stats->disk_usage; -		} -		if (trav_stats->disk_usage < alu_sched->min_limit.disk_usage) { -			alu_sched->min_limit.disk_usage = trav_stats->disk_usage; -		} - -		/* Select minimum and maximum disk_speed */ -		if (trav_stats->disk_speed > alu_sched->max_limit.disk_speed) { -			alu_sched->max_limit.disk_speed = trav_stats->disk_speed; -		} -		if (trav_stats->disk_speed < alu_sched->min_limit.disk_speed) { -			alu_sched->min_limit.disk_speed = trav_stats->disk_speed; -		} - -		/* Select minimum and maximum number of open files */ -		if (trav_stats->nr_files > alu_sched->max_limit.nr_files) { -			alu_sched->max_limit.nr_files = trav_stats->nr_files; -		} -		if (trav_stats->nr_files < alu_sched->min_limit.nr_files) { -			alu_sched->min_limit.nr_files = trav_stats->nr_files; -		} - -		/* Select minimum and maximum write-usage */ -		if (trav_stats->write_usage > alu_sched->max_limit.write_usage) { -			alu_sched->max_limit.write_usage = trav_stats->write_usage; -		} -		if (trav_stats->write_usage < alu_sched->min_limit.write_usage) { -			alu_sched->min_limit.write_usage = trav_stats->write_usage; -		} - -		/* Select minimum and maximum read-usage */ -		if (trav_stats->read_usage > alu_sched->max_limit.read_usage) { -			alu_sched->max_limit.read_usage = trav_stats->read_usage; -		} -		if (trav_stats->read_usage < alu_sched->min_limit.read_usage) { -			alu_sched->min_limit.read_usage = trav_stats->read_usage; -		} - -		/* Select minimum and maximum free-disk */ -		if (trav_stats->free_disk > alu_sched->max_limit.free_disk) { -			alu_sched->max_limit.free_disk = trav_stats->free_disk; -		} -		if (trav_stats->free_disk < alu_sched->min_limit.free_disk) { -			alu_sched->min_limit.free_disk = trav_stats->free_disk; -		} -	} - -	STACK_DESTROY (frame->root); - -	return 0; -} - -static void  -update_stat_array (xlator_t *xl) -{ -	/* This function schedules the file in one of the child nodes */ -	struct alu_sched *alu_sched = (struct alu_sched *)*((long *)xl->private); -	int32_t idx = 0; -	call_frame_t *frame = NULL; -	call_pool_t *pool = xl->ctx->pool; - -	for (idx = 0 ; idx < alu_sched->child_count; idx++) { -		frame = create_frame (xl, pool); - -		STACK_WIND_COOKIE (frame, -				   update_stat_array_cbk,  -				   alu_sched->array[idx].xl, //cookie -				   alu_sched->array[idx].xl,  -				   (alu_sched->array[idx].xl)->mops->stats, -				   0); //flag -	} -	return; -} - -static void  -alu_update (xlator_t *xl) -{ -	struct timeval tv; -	struct alu_sched *alu_sched = (struct alu_sched *)*((long *)xl->private); - -	gettimeofday (&tv, NULL); -	if (tv.tv_sec > (alu_sched->refresh_interval + alu_sched->last_stat_fetch.tv_sec)) { -		/* Update the stats from all the server */ -		update_stat_array (xl); -		alu_sched->last_stat_fetch.tv_sec = tv.tv_sec; -	} -} - -static xlator_t * -alu_scheduler (xlator_t *xl, const void *path) -{ -	/* This function schedules the file in one of the child nodes */ -	struct alu_sched *alu_sched = (struct alu_sched *)*((long *)xl->private); -	int32_t sched_index = 0; -	int32_t sched_index_orig = 0; -	int32_t idx = 0; - -	alu_update (xl); - -	/* Now check each threshold one by one if some nodes are classified */ -	{ -		struct alu_threshold *trav_threshold = alu_sched->threshold_fn; -		struct alu_threshold *tmp_threshold = alu_sched->sched_method; -		struct alu_sched_node *tmp_sched_node;    - -		/* This pointer 'trav_threshold' contains function pointers according to spec file -		   give by user, */ -		while (trav_threshold) { -			/* This check is needed for seeing if already there are nodes in this criteria  -			   to be scheduled */ -			if (!alu_sched->sched_nodes_pending) { -				for (idx = 0; idx < alu_sched->child_count; idx++) { -					if (!alu_sched->array[idx].eligible) { -						continue; -					} -					if (trav_threshold->entry_value) { -						if (trav_threshold->diff_value (&(alu_sched->max_limit), -										&(alu_sched->array[idx].stats)) < -						    trav_threshold->entry_value (&(alu_sched->entry_limit))) { -							continue; -						} -					} -					tmp_sched_node = GF_CALLOC (1, sizeof (struct alu_sched_node), gf_alu_mt_alu_sched_node); -					ERR_ABORT (tmp_sched_node); -					tmp_sched_node->index = idx; -					if (!alu_sched->sched_node) { -						alu_sched->sched_node = tmp_sched_node; -					} else { -						pthread_mutex_lock (&alu_sched->alu_mutex); -						tmp_sched_node->next = alu_sched->sched_node; -						alu_sched->sched_node = tmp_sched_node; -						pthread_mutex_unlock (&alu_sched->alu_mutex); -					} -					alu_sched->sched_nodes_pending++; -				} -			} /* end of if (sched_nodes_pending) */ - -			/* This loop is required to check the eligible nodes */ -			struct alu_sched_node *trav_sched_node; -			while (alu_sched->sched_nodes_pending) { -				trav_sched_node = alu_sched->sched_node; -				sched_index = trav_sched_node->index; -				if (alu_sched->array[sched_index].eligible) -					break; -				alu_sched->sched_node = trav_sched_node->next; -				GF_FREE (trav_sched_node); -				alu_sched->sched_nodes_pending--; -			} -			if (alu_sched->sched_nodes_pending) { -				/* There are some node in this criteria to be scheduled, no need  -				 * to sort and check other methods  -				 */ -				if (tmp_threshold && tmp_threshold->exit_value) { -					/* verify the exit value && whether node is eligible or not */ -					if (tmp_threshold->diff_value (&(alu_sched->max_limit), -								       &(alu_sched->array[sched_index].stats)) > -					    tmp_threshold->exit_value (&(alu_sched->exit_limit))) { -						/* Free the allocated info for the node :) */ -						pthread_mutex_lock (&alu_sched->alu_mutex); -						alu_sched->sched_node = trav_sched_node->next; -						GF_FREE (trav_sched_node); -						trav_sched_node = alu_sched->sched_node; -						alu_sched->sched_nodes_pending--; -						pthread_mutex_unlock (&alu_sched->alu_mutex); -					} -				} else { -					/* if there is no exit value, then exit after scheduling once */ -					pthread_mutex_lock (&alu_sched->alu_mutex); -					alu_sched->sched_node = trav_sched_node->next; -					GF_FREE (trav_sched_node); -					trav_sched_node = alu_sched->sched_node; -					alu_sched->sched_nodes_pending--; -					pthread_mutex_unlock (&alu_sched->alu_mutex); -				} -	 -				alu_sched->sched_method = tmp_threshold; /* this is the method used for selecting */ - -				/* */ -				if (trav_sched_node) { -					tmp_sched_node = trav_sched_node; -					while (trav_sched_node->next) { -						trav_sched_node = trav_sched_node->next; -					} -					if (tmp_sched_node->next) { -						pthread_mutex_lock (&alu_sched->alu_mutex); -						alu_sched->sched_node = tmp_sched_node->next; -						tmp_sched_node->next = NULL; -						trav_sched_node->next = tmp_sched_node; -						pthread_mutex_unlock (&alu_sched->alu_mutex); -					} -				} -				/* return the scheduled node */ -				return alu_sched->array[sched_index].xl; -			} /* end of if (pending_nodes) */ -       -			tmp_threshold = trav_threshold; -			trav_threshold = trav_threshold->next; -		} -	} -   -	/* This is used only when there is everything seems ok, or no eligible nodes */ -	sched_index_orig = alu_sched->sched_index; -	alu_sched->sched_method = NULL; -	while (1) { -		//lock -		pthread_mutex_lock (&alu_sched->alu_mutex); -		sched_index = alu_sched->sched_index++; -		alu_sched->sched_index = alu_sched->sched_index % alu_sched->child_count; -		pthread_mutex_unlock (&alu_sched->alu_mutex); -		//unlock -		if (alu_sched->array[sched_index].eligible) -			break; -		if (sched_index_orig == (sched_index + 1) % alu_sched->child_count) { -			gf_log ("alu", GF_LOG_WARNING, "No node is eligible to schedule"); -			//lock -			pthread_mutex_lock (&alu_sched->alu_mutex); -			alu_sched->sched_index++; -			alu_sched->sched_index = alu_sched->sched_index % alu_sched->child_count; -			pthread_mutex_unlock (&alu_sched->alu_mutex); -			//unlock -			break; -		} -	} -	return alu_sched->array[sched_index].xl; -} - -/** - * notify - */ -void -alu_notify (xlator_t *xl, int32_t event, void *data) -{ -	struct alu_sched *alu_sched = NULL;  -	int32_t idx = 0; -   -	alu_sched = (struct alu_sched *)*((long *)xl->private); -	if (!alu_sched) -		return; - -	for (idx = 0; idx < alu_sched->child_count; idx++) { -		if (alu_sched->array[idx].xl == (xlator_t *)data) -			break; -	} - -	switch (event) -	{ -	case GF_EVENT_CHILD_UP: -	{ -		//alu_sched->array[idx].eligible = 1; -	} -	break; -	case GF_EVENT_CHILD_DOWN: -	{ -		alu_sched->array[idx].eligible = 0; -	} -	break; -	default: -	{ -		; -	} -	break; -	} - -} - -int32_t -alu_mem_acct_init (xlator_t *this) -{ -        int     ret = -1; - -        if (!this) -                return ret; - -        ret = xlator_mem_acct_init (this, gf_alu_mt_end + 1); -         -        if (ret != 0) { -                gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" -                                "failed"); -                return ret; -        } - -        return ret; -} - -struct sched_ops sched = { -	.init     = alu_init, -	.fini     = alu_fini, -	.update   = alu_update, -	.schedule = alu_scheduler, -	.notify   = alu_notify, -        .mem_acct_init = alu_mem_acct_init, -}; - -struct volume_options options[] = { -	{ .key   = { "scheduler.alu.order", "alu.order" },   -	  .type  = GF_OPTION_TYPE_ANY  -	}, -	{ .key   = { "scheduler.alu.disk-usage.entry-threshold",  -		     "alu.disk-usage.entry-threshold" },   -	  .type  = GF_OPTION_TYPE_SIZET -	}, -	{ .key   = { "scheduler.alu.disk-usage.exit-threshold",  -		     "alu.disk-usage.exit-threshold" },   -	  .type  = GF_OPTION_TYPE_SIZET -	}, -	{ .key   = { "scheduler.alu.write-usage.entry-threshold",  -		     "alu.write-usage.entry-threshold" },   -	  .type  = GF_OPTION_TYPE_SIZET -	}, -	{ .key   = { "scheduler.alu.write-usage.exit-threshold",  -		     "alu.write-usage.exit-threshold" },   -	  .type  = GF_OPTION_TYPE_SIZET  -	}, -	{ .key   = { "scheduler.alu.read-usage.entry-threshold",  -		     "alu.read-usage.entry-threshold" },   -	  .type  = GF_OPTION_TYPE_SIZET -	}, -	{ .key   = { "scheduler.alu.read-usage.exit-threshold",  -		     "alu.read-usage.exit-threshold" },   -	  .type  = GF_OPTION_TYPE_SIZET  -	}, -	{ .key   = { "scheduler.alu.open-files-usage.entry-threshold",  -		     "alu.open-files-usage.entry-threshold" },   -	  .type  = GF_OPTION_TYPE_INT -	}, -	{ .key   = { "scheduler.alu.open-files-usage.exit-threshold",  -		     "alu.open-files-usage.exit-threshold" },   -	  .type  = GF_OPTION_TYPE_INT  -	}, -	{ .key   = { "scheduler.read-only-subvolumes", -		     "alu.read-only-subvolumes" },   -	  .type  = GF_OPTION_TYPE_ANY  -	}, -	{ .key   = { "scheduler.refresh-interval",  -		     "alu.refresh-interval", -		     "alu.stat-refresh.interval" }, -	  .type  = GF_OPTION_TYPE_TIME -	}, -	{ .key   = { "scheduler.limits.min-free-disk",  -		     "alu.limits.min-free-disk" },   -	  .type  = GF_OPTION_TYPE_PERCENT -	}, -	{ .key   = { "scheduler.alu.stat-refresh.num-file-create" -		     "alu.stat-refresh.num-file-create"},   -	  .type  = GF_OPTION_TYPE_INT -	}, -	{ .key  =  {NULL}, } -}; diff --git a/scheduler/alu/src/alu.h b/scheduler/alu/src/alu.h deleted file mode 100644 index c716ad8e5e7..00000000000 --- a/scheduler/alu/src/alu.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -   Copyright (c) 2006-2011 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/>. -*/ - -#ifndef _ALU_H -#define _ALU_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "scheduler.h" - -struct alu_sched; - -struct alu_sched_struct { -  xlator_t *xl; -  struct xlator_stats stats; -  unsigned char eligible; -}; - -// Write better name for these functions -struct alu_limits { -  struct alu_limits *next; -  int64_t (*max_value) (struct xlator_stats *); /* Max limit, specified by the user */ -  int64_t (*min_value) (struct xlator_stats *); /* Min limit, specified by the user */ -  int64_t (*cur_value) (struct xlator_stats *); /* Current values of variables got from stats call */ -}; - -struct alu_threshold { -  struct alu_threshold *next; -  int64_t (*diff_value) (struct xlator_stats *max, struct xlator_stats *min); /* Diff b/w max and min */ -  int64_t (*entry_value) (struct xlator_stats *); /* Limit specified user */ -  int64_t (*exit_value) (struct xlator_stats *); /* Exit point for the limit */ -  int64_t (*sched_value) (struct xlator_stats *); /* This will return the index of the child area */ -}; - -struct alu_sched_node { -  struct alu_sched_node *next; -  int32_t index; -}; - -struct alu_sched { -  struct alu_limits *limits_fn; -  struct alu_threshold *threshold_fn; -  struct alu_sched_struct *array; -  struct alu_sched_node *sched_node; -  struct alu_threshold *sched_method; -  struct xlator_stats max_limit; -  struct xlator_stats min_limit; -  struct xlator_stats entry_limit; -  struct xlator_stats exit_limit; -  struct xlator_stats spec_limit;     /* User given limit */ - -  pthread_mutex_t alu_mutex; -  struct timeval last_stat_fetch; -  uint32_t refresh_interval;      /* in seconds */ -  uint32_t refresh_create_count;  /* num-file-create */ - -  int32_t sched_nodes_pending; - -  int32_t sched_index;  /* used for round robin scheduling in case of many nodes getting the criteria match. */ -  int32_t child_count; - -}; - -struct _alu_local_t { -  int32_t call_count; -}; - -typedef struct _alu_local_t alu_local_t; - -#endif /* _ALU_H */ diff --git a/scheduler/nufa/Makefile.am b/scheduler/nufa/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/scheduler/nufa/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/scheduler/nufa/src/Makefile.am b/scheduler/nufa/src/Makefile.am deleted file mode 100644 index 6eb3d39f1e2..00000000000 --- a/scheduler/nufa/src/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -sched_LTLIBRARIES = nufa.la -scheddir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler - -nufa_la_LDFLAGS = -module -avoidversion - -nufa_la_SOURCES = nufa.c -nufa_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) - -CLEANFILES =  diff --git a/scheduler/nufa/src/nufa-mem-types.h b/scheduler/nufa/src/nufa-mem-types.h deleted file mode 100644 index 945dafa7c31..00000000000 --- a/scheduler/nufa/src/nufa-mem-types.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -   Copyright (c) 2008-2011 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/>. -*/ - - -#ifndef __NUFA_MEM_TYPES_H__ -#define __NUFA_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_locks_mem_types_ { -        gf_nufa_mt_nufa_struct = gf_common_mt_end + 1, -        gf_nufa_mt_nufa_sched_struct, -        gf_nufa_mt_int32_t, -        gf_nufa_mt_end -}; -#endif - diff --git a/scheduler/nufa/src/nufa.c b/scheduler/nufa/src/nufa.c deleted file mode 100644 index 1bf477bdc2c..00000000000 --- a/scheduler/nufa/src/nufa.c +++ /dev/null @@ -1,429 +0,0 @@ -/* -  Copyright (c) 2006-2011 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/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <sys/time.h> - -#include "scheduler.h" -#include "common-utils.h" -#include "nufa-mem-types.h" - -struct nufa_sched_struct { -	xlator_t *xl; -	struct timeval last_stat_fetch; -	int64_t free_disk; -	int32_t refresh_interval; -	unsigned char eligible; -}; - -struct nufa_struct { -	struct nufa_sched_struct *array; -	struct timeval last_stat_fetch; - -	int32_t *local_array; /* Used to keep the index of the local xlators */ -	int32_t local_xl_index; /* index in the above array */ -	int32_t local_xl_count; /* Count of the local subvolumes */ - -	uint32_t refresh_interval; -	uint32_t min_free_disk; -   -	gf_lock_t nufa_lock; -	int32_t child_count; -	int32_t sched_index;   -}; - -#define NUFA_LIMITS_MIN_FREE_DISK_DEFAULT    15 -#define NUFA_REFRESH_INTERVAL_DEFAULT        30 - -static int32_t -nufa_init (xlator_t *xl) -{ -	int32_t index = 0; -	data_t *local_name = NULL; -	data_t *data = NULL; -	xlator_list_t *trav_xl = xl->children; -	struct nufa_struct *nufa_buf = NULL; - -	nufa_buf = GF_CALLOC (1, sizeof (struct nufa_struct), -                              gf_nufa_mt_nufa_struct); -	ERR_ABORT (nufa_buf); - -	data = dict_get (xl->options, "scheduler.limits.min-free-disk"); -	if (data) { -		if (gf_string2percent (data->data,  -				       &nufa_buf->min_free_disk) != 0) { -			gf_log ("nufa", GF_LOG_ERROR,  -				"invalid number format \"%s\" of " -				"\"option scheduler.limits.min-free-disk\"",  -				data->data); -			return -1; -		} -		if (nufa_buf->min_free_disk >= 100) { -			gf_log ("nufa", GF_LOG_ERROR, -				"check \"option scheduler.limits.min-free-disk" -				"\", it should be percentage value"); -			return -1; -		} -	} else { -		gf_log ("nufa", GF_LOG_WARNING,  -			"No option for limit min-free-disk given, " -			"defaulting it to 15%%"); -		nufa_buf->min_free_disk = NUFA_LIMITS_MIN_FREE_DISK_DEFAULT; -	} -	data = dict_get (xl->options, "scheduler.refresh-interval"); -	if (data != NULL) { -                if (gf_string2time (data->data,  -				    &nufa_buf->refresh_interval) != 0) { -                        gf_log ("nufa", GF_LOG_ERROR,  -                                "invalid number format \"%s\" of " -                                "\"option scheduler.refresh-interval\"",  -                                data->data); -                        return -1; -                } -        } else { -		gf_log ("nufa", GF_LOG_WARNING,  -			"No option for scheduler.refresh-interval given, " -			"defaulting it to 30"); -		nufa_buf->refresh_interval = NUFA_REFRESH_INTERVAL_DEFAULT; -	} -   -	/* Get the array built */ -	while (trav_xl) { -		index++; -		trav_xl = trav_xl->next; -	} -	nufa_buf->child_count = index; -	nufa_buf->sched_index = 0; -	nufa_buf->array = GF_CALLOC (index, sizeof (struct nufa_sched_struct), -                                     gf_nufa_mt_nufa_sched_struct); -	ERR_ABORT (nufa_buf->array); -	nufa_buf->local_array = GF_CALLOC (index, sizeof (int32_t), -                                           gf_nufa_mt_int32_t); -	ERR_ABORT (nufa_buf->array); -	trav_xl = xl->children; -	 -	local_name = dict_get (xl->options, "scheduler.local-volume-name"); -	if (!local_name) { -		/* Error */ -		gf_log ("nufa", GF_LOG_ERROR,  -			"No 'local-volume-name' option given in volume file"); -		GF_FREE (nufa_buf->array); -		GF_FREE (nufa_buf->local_array); -		GF_FREE (nufa_buf); -		return -1; -	} - -	/* Get the array properly */ -	index = 0; -	trav_xl = xl->children; -	while (trav_xl) { -		nufa_buf->array[index].xl = trav_xl->xlator; -		nufa_buf->array[index].eligible = 1; -		nufa_buf->array[index].free_disk = nufa_buf->min_free_disk; -		nufa_buf->array[index].refresh_interval =  -			nufa_buf->refresh_interval; - -		trav_xl = trav_xl->next; -		index++; -	} -   -	{  -		int32_t array_index = 0; -		char *child = NULL; -		char *tmp = NULL; -		char *childs_data = gf_strdup (local_name->data); -		 -		child = strtok_r (childs_data, ",", &tmp); -		while (child) { -			/* Check if the local_volume specified is proper  -			   subvolume of unify */ -			trav_xl = xl->children; -			index=0; -			while (trav_xl) { -				if (strcmp (child, trav_xl->xlator->name) == 0) -					break; -				trav_xl = trav_xl->next; -				index++; -			} - -			if (!trav_xl) { -				/* entry for 'local-volume-name' is wrong,  -				   not present in subvolumes */ -				gf_log ("nufa", GF_LOG_ERROR,  -					"option 'scheduler.local-volume-name' " -					"%s is wrong", child); -				GF_FREE (nufa_buf->array); -				GF_FREE (nufa_buf->local_array); -				GF_FREE (nufa_buf); -				return -1; -			} else { -				nufa_buf->local_array[array_index++] = index; -				nufa_buf->local_xl_count++; -			} -			child = strtok_r (NULL, ",", &tmp); -		} -		GF_FREE (childs_data); -	} - -	LOCK_INIT (&nufa_buf->nufa_lock); -	*((long *)xl->private) = (long)nufa_buf; // put it at the proper place -	return 0; -} - -static void -nufa_fini (xlator_t *xl) -{ -	struct nufa_struct *nufa_buf =  -		(struct nufa_struct *)*((long *)xl->private); - -	LOCK_DESTROY (&nufa_buf->nufa_lock); -	GF_FREE (nufa_buf->local_array); -	GF_FREE (nufa_buf->array); -	GF_FREE (nufa_buf); -} - -static int32_t  -update_stat_array_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *xl, -		       int32_t op_ret, -		       int32_t op_errno, -		       struct xlator_stats *trav_stats) -{ -	struct nufa_struct *nufa_struct = NULL;  -	int32_t idx = 0; -	int32_t percent = 0; - -	nufa_struct = (struct nufa_struct *)*((long *)xl->private); -	LOCK (&nufa_struct->nufa_lock); -	for (idx = 0; idx < nufa_struct->child_count; idx++) { -		if (nufa_struct->array[idx].xl->name == (char *)cookie) -			break; -	} -	UNLOCK (&nufa_struct->nufa_lock); - -	if (op_ret == 0) { -		percent = ((trav_stats->free_disk * 100) /  -			   trav_stats->total_disk_size); -		if (nufa_struct->array[idx].free_disk > percent) { -			if (nufa_struct->array[idx].eligible) -				gf_log ("nufa", GF_LOG_CRITICAL, -					"node \"%s\" is _almost_ (%d %%) full", -					nufa_struct->array[idx].xl->name,  -					100 - percent); -			nufa_struct->array[idx].eligible = 0; -		} else { -			nufa_struct->array[idx].eligible = 1; -		} -	} else { -		nufa_struct->array[idx].eligible = 0; -	} - -	STACK_DESTROY (frame->root); -	return 0; -} - -static void  -update_stat_array (xlator_t *xl) -{ -	/* This function schedules the file in one of the child nodes */ -	int32_t idx; -	struct nufa_struct *nufa_buf =  -		(struct nufa_struct *)*((long *)xl->private); -	call_frame_t *frame = NULL; -	call_pool_t *pool = xl->ctx->pool; - -	for (idx = 0; idx < nufa_buf->child_count; idx++) { -		frame = create_frame (xl, pool); - -		STACK_WIND_COOKIE (frame, -				   update_stat_array_cbk,  -				   nufa_buf->array[idx].xl->name, -				   nufa_buf->array[idx].xl,  -				   (nufa_buf->array[idx].xl)->mops->stats, -				   0); //flag -	} - -	return; -} - -static void  -nufa_update (xlator_t *xl) -{ -	struct nufa_struct *nufa_buf =  -		(struct nufa_struct *)*((long *)xl->private); -	struct timeval tv; -	gettimeofday (&tv, NULL); -	if (tv.tv_sec > (nufa_buf->refresh_interval  -			 + nufa_buf->last_stat_fetch.tv_sec)) { -		/* Update the stats from all the server */ -		update_stat_array (xl); -		nufa_buf->last_stat_fetch.tv_sec = tv.tv_sec; -	} -} - -static xlator_t * -nufa_schedule (xlator_t *xl, const void *path) -{ -	struct nufa_struct *nufa_buf =  -		(struct nufa_struct *)*((long *)xl->private); -	int32_t nufa_orig = nufa_buf->local_xl_index;   -	int32_t rr; -   -	nufa_update (xl); -   -	while (1) { -		LOCK (&nufa_buf->nufa_lock); -		rr = nufa_buf->local_xl_index++; -		nufa_buf->local_xl_index %= nufa_buf->local_xl_count; -		UNLOCK (&nufa_buf->nufa_lock); -     -		/* if 'eligible' or there are _no_ eligible nodes */ -		if (nufa_buf->array[nufa_buf->local_array[rr]].eligible) { -			/* Return the local node */ -			return nufa_buf->array[nufa_buf->local_array[rr]].xl; -		} -		if ((rr + 1) % nufa_buf->local_xl_count == nufa_orig) { -			gf_log ("nufa", GF_LOG_CRITICAL,  -				"No free space available on any local " -				"volumes, using RR scheduler"); -			LOCK (&nufa_buf->nufa_lock); -			nufa_buf->local_xl_index++; -			nufa_buf->local_xl_index %= nufa_buf->local_xl_count; -			UNLOCK (&nufa_buf->nufa_lock); -			break; -		} -	} - -	nufa_orig = nufa_buf->sched_index;   -	while (1) { -		LOCK (&nufa_buf->nufa_lock); -		rr = nufa_buf->sched_index++; -		nufa_buf->sched_index = (nufa_buf->sched_index %  -					 nufa_buf->child_count); -		UNLOCK (&nufa_buf->nufa_lock); -     -		/* if 'eligible' or there are _no_ eligible nodes */ -		if (nufa_buf->array[rr].eligible) { -			break; -		} -		if ((rr + 1) % nufa_buf->child_count == nufa_orig) { -			gf_log ("nufa", GF_LOG_CRITICAL,  -				"No free space available on any server, " -				"using RR scheduler."); -			LOCK (&nufa_buf->nufa_lock); -			nufa_buf->sched_index++; -			nufa_buf->sched_index = (nufa_buf->sched_index %  -						 nufa_buf->child_count); -			UNLOCK (&nufa_buf->nufa_lock); -			break; -		} -	} -	return nufa_buf->array[rr].xl; -} - - -/** - * notify - */ -void -nufa_notify (xlator_t *xl, int32_t event, void *data) -{ -	struct nufa_struct *nufa_buf =  -		(struct nufa_struct *)*((long *)xl->private); -	int32_t idx = 0; -   -	if (!nufa_buf) -		return; - -	for (idx = 0; idx < nufa_buf->child_count; idx++) { -		if (strcmp (nufa_buf->array[idx].xl->name,  -			    ((xlator_t *)data)->name) == 0) -			break; -	} - -	switch (event) -	{ -	case GF_EVENT_CHILD_UP: -	{ -		//nufa_buf->array[idx].eligible = 1; -	} -	break; -	case GF_EVENT_CHILD_DOWN: -	{ -		nufa_buf->array[idx].eligible = 0; -	} -	break; -	default: -	{ -		; -	} -	break; -	} - -} - -int32_t -nufa_mem_acct_init (xlator_t *this) -{ -        int     ret = -1; - -        if (!this) -                return ret; - -        ret = xlator_mem_acct_init (this, gf_nufa_mt_end + 1); -         -        if (ret != 0) { -                gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" -                                "failed"); -                return ret; -        } - -        return ret; -} - -struct sched_ops sched = { -	.init     = nufa_init, -	.fini     = nufa_fini, -	.update   = nufa_update, -	.schedule = nufa_schedule, -	.notify   = nufa_notify, -        .mem_acct_init = nufa_mem_acct_init, -}; - -struct volume_options options[] = { -	{ .key   = { "scheduler.refresh-interval",  -		     "nufa.refresh-interval" },   -	  .type  = GF_OPTION_TYPE_TIME -	}, -	{ .key   = { "scheduler.limits.min-free-disk",  -		     "nufa.limits.min-free-disk" },   -	  .type  = GF_OPTION_TYPE_PERCENT -	}, -	{ .key   = { "scheduler.local-volume-name", -		     "nufa.local-volume-name" }, -	  .type  = GF_OPTION_TYPE_XLATOR -	},	 -	{ .key = {NULL} } -}; - diff --git a/scheduler/random/Makefile.am b/scheduler/random/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/scheduler/random/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/scheduler/random/src/Makefile.am b/scheduler/random/src/Makefile.am deleted file mode 100644 index 572181336c2..00000000000 --- a/scheduler/random/src/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -sched_LTLIBRARIES = random.la -scheddir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler - -random_la_LDFLAGS = -module -avoidversion - -random_la_SOURCES = random.c -random_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -noinst_HEADERS = random.h - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) - -CLEANFILES =  diff --git a/scheduler/random/src/random-mem-types.h b/scheduler/random/src/random-mem-types.h deleted file mode 100644 index ff30d9244fc..00000000000 --- a/scheduler/random/src/random-mem-types.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -   Copyright (c) 2008-2011 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/>. -*/ - - -#ifndef __RANDOM_MEM_TYPES_H__ -#define __RANDOM_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_random_mem_types_ { -        gf_random_mt_random_struct = gf_common_mt_end + 1, -        gf_random_mt_random_sched_struct, -        gf_random_mt_end -}; -#endif - diff --git a/scheduler/random/src/random.c b/scheduler/random/src/random.c deleted file mode 100644 index 03a284b66bd..00000000000 --- a/scheduler/random/src/random.c +++ /dev/null @@ -1,305 +0,0 @@ -/* -  Copyright (c) 2006-2011 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 <stdlib.h> -#include <sys/time.h> - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "random.h" -#include "random-mem-types.h" - -#define RANDOM_LIMITS_MIN_FREE_DISK_DEFAULT    15 -#define RANDOM_REFRESH_INTERVAL_DEFAULT        10 - - -static int32_t -random_init (xlator_t *xl) -{ -	struct random_struct *random_buf = NULL; -	xlator_list_t *trav_xl = xl->children; -	data_t *limit = NULL; -	int32_t index = 0; - -	random_buf = GF_CALLOC (1, sizeof (struct random_struct), -                                gf_random_mt_random_struct); -	ERR_ABORT (random_buf); -   -	/* Set the seed for the 'random' function */ -	srandom ((uint32_t) time (NULL)); -   -	limit = dict_get (xl->options, "scheduler.limits.min-free-disk"); -	if (limit) { -		if (gf_string2percent (data_to_str (limit), -				       &random_buf->min_free_disk) != 0) { -			gf_log ("random", GF_LOG_ERROR,  -				"invalid number format \"%s\" of \"option " -				"scheduler.limits.min-free-disk\"",  -				limit->data); -			return -1; -		} -		if (random_buf->min_free_disk >= 100) { -			gf_log ("random", GF_LOG_ERROR, -				"check the \"option random.limits.min-free" -				"-disk\", it should be percentage value"); -			return -1; -		} -       -	} else { -		gf_log ("random", GF_LOG_WARNING,  -			"No option for limit min-free-disk given, " -			"defaulting it to 5%%"); -		random_buf->min_free_disk =  -			RANDOM_LIMITS_MIN_FREE_DISK_DEFAULT; -	} -   -	limit = dict_get (xl->options, "scheduler.refresh-interval"); -	if (limit) { -		if (gf_string2time (data_to_str (limit), -				    &random_buf->refresh_interval) != 0) { -			gf_log ("random", GF_LOG_ERROR,  -				"invalid number format \"%s\" of " -				"\"option random.refresh-interval\"",  -				limit->data); -			return -1; -		} -	} else { -		random_buf->refresh_interval = RANDOM_REFRESH_INTERVAL_DEFAULT; -	} -   -	while (trav_xl) { -		index++; -		trav_xl = trav_xl->next; -	} -	random_buf->child_count = index; -	random_buf->array = GF_CALLOC (index, -                                       sizeof (struct random_sched_struct), -                                       gf_random_mt_random_sched_struct); -	ERR_ABORT (random_buf->array); -	trav_xl = xl->children; -	index = 0; - -	while (trav_xl) { -		random_buf->array[index].xl = trav_xl->xlator; -		random_buf->array[index].eligible = 1; -		trav_xl = trav_xl->next; -		index++; -	} -	pthread_mutex_init (&random_buf->random_mutex, NULL); - -	// put it at the proper place   -	*((long *)xl->private) = (long)random_buf;  -	return 0; -} - -static void -random_fini (xlator_t *xl) -{ -	struct random_struct *random_buf = NULL; - -	random_buf = (struct random_struct *)*((long *)xl->private); -	pthread_mutex_destroy (&random_buf->random_mutex); -	GF_FREE (random_buf->array); -	GF_FREE (random_buf); -} - - -static int32_t  -update_stat_array_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *xl, -		       int32_t op_ret, -		       int32_t op_errno, -		       struct xlator_stats *trav_stats) -{ -	int32_t idx = 0; -	int32_t percent = 0; -	struct random_struct *random_buf = NULL; -	 -	random_buf = (struct random_struct *)*((long *)xl->private); - -	pthread_mutex_lock (&random_buf->random_mutex); -	for (idx = 0; idx < random_buf->child_count; idx++) { -		if (strcmp (random_buf->array[idx].xl->name,  -			    (char *)cookie) == 0) -			break; -	} -	pthread_mutex_unlock (&random_buf->random_mutex); - -	if (op_ret == 0) { -		percent = ((trav_stats->free_disk *100) /  -			   trav_stats->total_disk_size); -		if (random_buf->min_free_disk > percent) { -			random_buf->array[idx].eligible = 0; -		} else { -			random_buf->array[idx].eligible = 1; -		} -	} else { -		random_buf->array[idx].eligible = 0; -	}     - -	STACK_DESTROY (frame->root); -	return 0; -} - -static void  -update_stat_array (xlator_t *xl) -{ -	int32_t idx; -	struct random_struct *random_buf = NULL; -	call_frame_t *frame = NULL; -	call_pool_t *pool = xl->ctx->pool; - -	random_buf = (struct random_struct *)*((long *)xl->private); -	for (idx = 0; idx < random_buf->child_count; idx++) { -		frame = create_frame (xl, pool); - -		STACK_WIND_COOKIE (frame, -				   update_stat_array_cbk, -				   random_buf->array[idx].xl->name, -				   random_buf->array[idx].xl, -				   (random_buf->array[idx].xl)->mops->stats, -				   0); -	} -	return ; -} - -static void  -random_update (xlator_t *xl) -{ -	struct timeval tv; -	struct random_struct *random_buf = NULL; - -	random_buf = (struct random_struct *)*((long *)xl->private); - -	gettimeofday(&tv, NULL); -	if (tv.tv_sec > (random_buf->refresh_interval +  -			 random_buf->last_stat_entry.tv_sec)) { -		update_stat_array (xl); -		random_buf->last_stat_entry.tv_sec = tv.tv_sec; -	} -} - -static xlator_t * -random_schedule (xlator_t *xl, const void *path) -{ -	struct random_struct *random_buf = NULL;        -	int32_t rand = 0; -	int32_t try = 0; -	 -	random_buf = (struct random_struct *)*((long *)xl->private); - -	rand = (int32_t) (1.0*random_buf->child_count *  -			  (random() / (RAND_MAX + 1.0))); - -	random_update (xl); - -	while (!random_buf->array[rand].eligible) { -		if (try++ > 100) { -			/* there is a chance of this becoming a  -			   infinite loop otherwise. */ -			break;  -		} -		rand = (int32_t) (1.0*random_buf->child_count *  -				  (random() / (RAND_MAX + 1.0))); -	} -	return random_buf->array[rand].xl; -} - -int32_t -random_mem_acct_init (xlator_t *this) -{ -        int     ret = -1; - -        if (!this) -                return ret; - -        ret = xlator_mem_acct_init (this, gf_random_mt_end + 1); -         -        if (ret != 0) { -                gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" -                        " failed"); -                return ret; -        } - -        return ret; -} - -/** - * notify - */ -void -random_notify (xlator_t *xl, int32_t event, void *data) -{ -	struct random_struct *random_buf = NULL; -	int32_t idx = 0; -   -	random_buf = (struct random_struct *)*((long *)xl->private); -	if (!random_buf) -		return; - -	for (idx = 0; idx < random_buf->child_count; idx++) { -		if (random_buf->array[idx].xl == (xlator_t *)data) -			break; -	} - -	switch (event) -	{ -	case GF_EVENT_CHILD_UP: -	{ -		//random_buf->array[idx].eligible = 1; -	} -	break; -	case GF_EVENT_CHILD_DOWN: -	{ -		random_buf->array[idx].eligible = 0; -	} -	break; -	default: -	{ -		; -	} -	break; -	} - -} - -struct sched_ops sched = { -	.init     = random_init, -	.fini     = random_fini, -	.update   = random_update, -	.schedule = random_schedule, -	.notify   = random_notify, -        .mem_acct_init = random_mem_acct_init, -}; - -struct volume_options options[] = { -	{ .key   = { "scheduler.refresh-interval",  -		     "random.refresh-interval" },   -	  .type  = GF_OPTION_TYPE_TIME -	}, -	{ .key   = { "scheduler.limits.min-free-disk",  -		     "random.limits.min-free-disk" },   -	  .type  = GF_OPTION_TYPE_PERCENT -	}, -	{ .key = {NULL} } -}; diff --git a/scheduler/random/src/random.h b/scheduler/random/src/random.h deleted file mode 100644 index 154b1bdfb24..00000000000 --- a/scheduler/random/src/random.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -   Copyright (c) 2006-2011 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/>. -*/ - -#ifndef _RANDOM_H -#define _RANDOM_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - - -#include <sys/time.h> -#include "scheduler.h" - -struct random_sched_struct { -  xlator_t *xl; -  unsigned char eligible; -}; - -struct random_struct { -  int32_t child_count; -  uint32_t refresh_interval; -  uint32_t min_free_disk; -  struct timeval last_stat_entry; -  struct random_sched_struct *array; -  pthread_mutex_t random_mutex; -}; - -#endif /* _RANDOM_H */ diff --git a/scheduler/rr/Makefile.am b/scheduler/rr/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/scheduler/rr/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/scheduler/rr/src/Makefile.am b/scheduler/rr/src/Makefile.am deleted file mode 100644 index 7e911c0eda8..00000000000 --- a/scheduler/rr/src/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -sched_LTLIBRARIES = rr.la -scheddir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler - -rr_la_LDFLAGS = -module -avoidversion - -rr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -rr_la_SOURCES = rr.c rr-options.c -noinst_HEADERS = rr.h rr-options.h - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) - -CLEANFILES =  diff --git a/scheduler/rr/src/rr-mem-types.h b/scheduler/rr/src/rr-mem-types.h deleted file mode 100644 index cb05323cd77..00000000000 --- a/scheduler/rr/src/rr-mem-types.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -   Copyright (c) 2008-2011 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/>. -*/ - - -#ifndef __RR_MEM_TYPES_H__ -#define __RR_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_rr_mem_types_ { -        gf_rr_mt_rr_t = gf_common_mt_end + 1, -        gf_rr_mt_rr_subvolume_t, -        gf_rr_mt_end -}; -#endif - diff --git a/scheduler/rr/src/rr-options.c b/scheduler/rr/src/rr-options.c deleted file mode 100644 index 505b1713e33..00000000000 --- a/scheduler/rr/src/rr-options.c +++ /dev/null @@ -1,256 +0,0 @@ -/* -  Copyright (c) 2008-2011 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 "scheduler.h" -#include "rr-options.h" - -#define RR_LIMITS_MIN_FREE_DISK_OPTION_STRING  "scheduler.limits.min-free-disk" -#define RR_LIMITS_MIN_FREE_DISK_VALUE_DEFAULT  15 -#define RR_LIMITS_MIN_FREE_DISK_VALUE_MIN      0 -#define RR_LIMITS_MIN_FREE_DISK_VALUE_MAX      100 - -#define RR_REFRESH_INTERVAL_OPTION_STRING      "scheduler.refresh-interval" -#define RR_REFRESH_INTERVAL_VALUE_DEFAULT      10 - -#define RR_READ_ONLY_SUBVOLUMES_OPTION_STRING  "scheduler.read-only-subvolumes" - -#define LOG_ERROR(args...)      gf_log ("rr-options", GF_LOG_ERROR, ##args) -#define LOG_WARNING(args...)    gf_log ("rr-options", GF_LOG_WARNING, ##args) - -static int  -_rr_options_min_free_disk_validate (const char *value_string, uint32_t *n) -{ -	uint32_t value = 0; -   -	if (value_string == NULL) -	{ -		return -1; -	} -   -	if (gf_string2percent (value_string, &value) != 0) -	{ -		gf_log ("rr",  -			GF_LOG_ERROR,  -			"invalid number format [%s] of option [%s]",  -			value_string,  -			RR_LIMITS_MIN_FREE_DISK_OPTION_STRING); -		return -1; -	} -   -	if ((value <= RR_LIMITS_MIN_FREE_DISK_VALUE_MIN) ||  -	    (value >= RR_LIMITS_MIN_FREE_DISK_VALUE_MAX)) -	{ -		gf_log ("rr",  -			GF_LOG_ERROR,  -			"out of range [%d] of option [%s].  Allowed range is 0 to 100.",  -			value,  -			RR_LIMITS_MIN_FREE_DISK_OPTION_STRING); -		return -1; -	} -   -	*n = value; -   -	return 0; -} - -static int  -_rr_options_refresh_interval_validate (const char *value_string, uint32_t *n) -{ -	uint32_t value = 0; -   -	if (value_string == NULL) -	{ -		return -1; -	} -   -	if (gf_string2time (value_string, &value) != 0) -	{ -		gf_log ("rr",  -			GF_LOG_ERROR,  -			"invalid number format [%s] of option [%s]",  -			value_string,  -			RR_REFRESH_INTERVAL_OPTION_STRING); -		return -1; -	} -   -	*n = value; -   -	return 0; -} - -static int  -_rr_options_read_only_subvolumes_validate (const char *value_string,  -					   char ***volume_list,  -					   uint64_t *volume_count) -{ -	char **vlist = NULL; -	int vcount = 0; -	int i = 0; -   -	if (value_string == NULL || volume_list == NULL || volume_count) -	{ -		return -1; -	} -   -	if (gf_strsplit (value_string,  -			 ", ",  -			 &vlist,  -			 &vcount) != 0) -	{ -		gf_log ("rr",  -			GF_LOG_ERROR,  -			"invalid subvolume list [%s] of option [%s]",  -			value_string,  -			RR_READ_ONLY_SUBVOLUMES_OPTION_STRING); -		return -1; -	} -   -	for (i = 0; i < vcount; i++) -	{ -		if (gf_volume_name_validate (vlist[i]) != 0) -		{ -			gf_log ("rr",  -				GF_LOG_ERROR,  -				"invalid subvolume name [%s] in [%s] of option [%s]",  -				vlist[i],  -				value_string,  -				RR_READ_ONLY_SUBVOLUMES_OPTION_STRING); -			goto free_exit; -		} -	} -   -	*volume_list = vlist; -	*volume_count = vcount; -   -	return 0; -   - free_exit: -	for (i = 0; i < vcount; i++) -	{ -		GF_FREE (vlist[i]); -	} -	GF_FREE (vlist); -   -	return -1; -} - -int  -rr_options_validate (dict_t *options, rr_options_t *rr_options) -{ -	char *value_string = NULL; -   -	if (options == NULL || rr_options == NULL) -	{ -		return -1; -	} -   -	if (dict_get (options, RR_LIMITS_MIN_FREE_DISK_OPTION_STRING)) -		if (data_to_str (dict_get (options, RR_LIMITS_MIN_FREE_DISK_OPTION_STRING))) -			value_string = data_to_str (dict_get (options,  -							      RR_LIMITS_MIN_FREE_DISK_OPTION_STRING)); -	if (value_string != NULL) -	{ -		if (_rr_options_min_free_disk_validate (value_string,  -							&rr_options->min_free_disk) != 0) -		{ -			return -1; -		} -       -		gf_log ("rr",  -			GF_LOG_WARNING,  -			"using %s = %d",  -			RR_LIMITS_MIN_FREE_DISK_OPTION_STRING,  -			rr_options->min_free_disk); -	} -	else  -	{ -		rr_options->min_free_disk = RR_LIMITS_MIN_FREE_DISK_VALUE_DEFAULT; -       -		gf_log ("rr", GF_LOG_DEBUG,  -			"using %s = %d [default]",  -			RR_LIMITS_MIN_FREE_DISK_OPTION_STRING,  -			rr_options->min_free_disk); -	} -   -	value_string = NULL; -	if (dict_get (options, RR_REFRESH_INTERVAL_OPTION_STRING)) -		value_string = data_to_str (dict_get (options,  -						      RR_REFRESH_INTERVAL_OPTION_STRING)); -	if (value_string != NULL) -	{ -		if (_rr_options_refresh_interval_validate (value_string,  -							   &rr_options->refresh_interval) != 0) -		{ -			return -1; -		} -       -		gf_log ("rr",  -			GF_LOG_WARNING,  -			"using %s = %d",  -			RR_REFRESH_INTERVAL_OPTION_STRING,  -			rr_options->refresh_interval); -	} -	else  -	{ -		rr_options->refresh_interval = RR_REFRESH_INTERVAL_VALUE_DEFAULT; -       -		gf_log ("rr", GF_LOG_DEBUG,  -			"using %s = %d [default]",  -			RR_REFRESH_INTERVAL_OPTION_STRING,  -			rr_options->refresh_interval); -	} -   -	value_string = NULL; -	if (dict_get (options, RR_READ_ONLY_SUBVOLUMES_OPTION_STRING)) -		value_string = data_to_str (dict_get (options,  -						      RR_READ_ONLY_SUBVOLUMES_OPTION_STRING)); -	if (value_string != NULL) -	{ -		if (_rr_options_read_only_subvolumes_validate (value_string,  -							       &rr_options->read_only_subvolume_list,  -							       &rr_options->read_only_subvolume_count) != 0) -		{ -			return -1; -		} -       -		gf_log ("rr",  -			GF_LOG_WARNING,  -			"using %s = [%s]",  -			RR_READ_ONLY_SUBVOLUMES_OPTION_STRING,  -			value_string); -	} -   -	return 0; -} - -struct volume_options options[] = { -	{ .key   = { "scheduler.refresh-interval",  -		     "rr.refresh-interval" },   -	  .type  = GF_OPTION_TYPE_TIME -	}, -	{ .key   = { "scheduler.limits.min-free-disk",  -		     "rr.limits.min-free-disk" },   -	  .type  = GF_OPTION_TYPE_PERCENT -	}, -	{ .key   = { "scheduler.read-only-subvolumes",  -		     "rr.read-only-subvolumes" },   -	  .type  = GF_OPTION_TYPE_ANY -	}, -	{ .key = {NULL} } -}; diff --git a/scheduler/rr/src/rr-options.h b/scheduler/rr/src/rr-options.h deleted file mode 100644 index 1b0a1ef3d90..00000000000 --- a/scheduler/rr/src/rr-options.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -   Copyright (c) 2008-2011 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/>. -*/ - -#ifndef _RR_OPTIONS_H -#define _RR_OPTIONS_H - -struct rr_options -{ -  uint32_t min_free_disk; -  uint32_t refresh_interval; -  char     **read_only_subvolume_list; -  uint64_t read_only_subvolume_count; -}; -typedef struct rr_options rr_options_t; - -int rr_options_validate (dict_t *options, rr_options_t *rr_options); - -#endif diff --git a/scheduler/rr/src/rr.c b/scheduler/rr/src/rr.c deleted file mode 100644 index e7b556e671b..00000000000 --- a/scheduler/rr/src/rr.c +++ /dev/null @@ -1,567 +0,0 @@ -/* -  Copyright (c) 2006-2011 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/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <sys/time.h> -#include <stdlib.h> - -#include <stdint.h> - -#include "scheduler.h" - -#include "rr-options.h" -#include "rr.h" -#include "rr-mem-types.h" - -#define RR_MIN_FREE_DISK_NOT_REACHED    0 -#define RR_MIN_FREE_DISK_REACHED        1 - -#define RR_SUBVOLUME_OFFLINE    0 -#define RR_SUBVOLUME_ONLINE     1 - -#define LOG_ERROR(args...)      gf_log ("rr", GF_LOG_ERROR, ##args) -#define LOG_WARNING(args...)    gf_log ("rr", GF_LOG_WARNING, ##args) -#define LOG_CRITICAL(args...)    gf_log ("rr", GF_LOG_CRITICAL, ##args) - -#define ROUND_ROBIN(index, count)    ((index + 1) % count) - -static int  -_cleanup_rr (rr_t *rr) -{ -	int i; -   -	if (rr == NULL) -	{ -		return -1; -	} -   -	if (rr->options.read_only_subvolume_list != NULL) -	{ -		for (i = 0; i < rr->options.read_only_subvolume_count; i++) -		{ -			GF_FREE (rr->options.read_only_subvolume_list[i]); -		} -		GF_FREE (rr->options.read_only_subvolume_list); -	} -   -	GF_FREE (rr->subvolume_list); -   -	GF_FREE (rr); -   -	return 0; -} - -int  -rr_init (xlator_t *this_xl) -{ -	rr_t *rr = NULL; -	dict_t *options = NULL; -	xlator_list_t *children = NULL; -	uint64_t children_count = 0; -	int i = 0; -	int j = 0; -   -	if (this_xl == NULL) -	{ -		return -1; -	} -   -	if ((options = this_xl->options) == NULL) -	{ -		return -1; -	} -   -	if ((children = this_xl->children) == NULL) -	{ -		return -1; -	} -   -	if ((rr = GF_CALLOC (1, sizeof (rr_t), gf_rr_mt_rr_t)) == NULL) -	{ -		return -1; -	} -   -	if (rr_options_validate (options, &rr->options) != 0) -	{ -		GF_FREE (rr); -		return -1; -	} -   -	for (i = 0; i < rr->options.read_only_subvolume_count; i++) -	{ -		char found = 0; -       -		for (children = this_xl->children;  -		     children != NULL;  -		     children = children->next) -		{ -			if (strcmp (rr->options.read_only_subvolume_list[i],  -				    children->xlator->name) == 0) -			{ -				found = 1; -				break; -			} -		} -       -		if (!found) -		{ -			LOG_ERROR ("read-only subvolume [%s] not found in volume list",  -				   rr->options.read_only_subvolume_list[i]); -			_cleanup_rr (rr); -			return -1; -		} -	} -   -	for (children = this_xl->children;  -	     children != NULL;  -	     children = children->next) -	{ -		children_count++; -	} -   -	/* bala: excluding read_only_subvolumes */ -	if ((rr->subvolume_count = children_count -  -	     rr->options.read_only_subvolume_count) == 0) -	{ -		LOG_ERROR ("no writable volumes found for scheduling"); -		_cleanup_rr (rr); -		return -1; -	} -   -	if ((rr->subvolume_list = GF_CALLOC (rr->subvolume_count,  -                                             sizeof (rr_subvolume_t), -                                             gf_rr_mt_rr_subvolume_t)) == NULL) -	{ -		_cleanup_rr (rr); -		return -1; -	} -   -	i = 0; -	j = 0; -	for (children = this_xl->children;  -	     children != NULL;  -	     children = children->next) -	{ -		char found = 0; -       -		for (j = 0; j < rr->options.read_only_subvolume_count; j++) -		{ -			if (strcmp (rr->options.read_only_subvolume_list[i],  -				    children->xlator->name) == 0) -			{ -				found = 1; -				break; -			} -		} -       -		if (!found) -		{ -			rr_subvolume_t *subvolume = NULL; -	   -			subvolume = &rr->subvolume_list[i]; -	   -			subvolume->xl = children->xlator; -			subvolume->free_disk_status = RR_MIN_FREE_DISK_NOT_REACHED; -			subvolume->status = RR_SUBVOLUME_ONLINE; -	   -			i++; -		} -	} -   -	rr->schedule_index = UINT64_MAX; -	rr->last_stat_fetched_time.tv_sec = 0; -	rr->last_stat_fetched_time.tv_usec = 0; -	pthread_mutex_init (&rr->mutex, NULL); -   -	*((long *)this_xl->private) = (long)rr; -   -	return 0; -} - -void  -rr_fini (xlator_t *this_xl) -{ -	rr_t *rr = NULL; -   -	if (this_xl == NULL) -	{ -		return; -	} -   -	if ((rr = (rr_t *) *((long *)this_xl->private)) != NULL) -	{ -		pthread_mutex_destroy (&rr->mutex); -		_cleanup_rr (rr); -		this_xl->private = NULL; -	} -   -	return; -} - -xlator_t * -rr_schedule (xlator_t *this_xl, const void *path) -{ -	rr_t *rr = NULL; -	uint64_t next_schedule_index = 0; -	int i = 0; -   -	if (this_xl == NULL || path == NULL) -	{ -		return NULL; -	} -   -	rr = (rr_t *) *((long *)this_xl->private); -	next_schedule_index = ROUND_ROBIN (rr->schedule_index,  -					   rr->subvolume_count); -   -	rr_update (this_xl); -   -	for (i = next_schedule_index; i < rr->subvolume_count; i++) -	{ -		if (rr->subvolume_list[i].status == RR_SUBVOLUME_ONLINE &&  -		    rr->subvolume_list[i].status == RR_MIN_FREE_DISK_NOT_REACHED) -		{ -			pthread_mutex_lock (&rr->mutex); -			rr->schedule_index = i; -			pthread_mutex_unlock (&rr->mutex); -			return rr->subvolume_list[i].xl; -		} -	} -   -	for (i = 0; i < next_schedule_index; i++) -	{ -		if (rr->subvolume_list[i].status == RR_SUBVOLUME_ONLINE &&  -		    rr->subvolume_list[i].status == RR_MIN_FREE_DISK_NOT_REACHED) -		{ -			pthread_mutex_lock (&rr->mutex); -			rr->schedule_index = i; -			pthread_mutex_unlock (&rr->mutex); -			return rr->subvolume_list[i].xl; -		} -	} -   -	for (i = next_schedule_index; i < rr->subvolume_count; i++) -	{ -		if (rr->subvolume_list[i].status == RR_SUBVOLUME_ONLINE) -		{ -			pthread_mutex_lock (&rr->mutex); -			rr->schedule_index = i; -			pthread_mutex_unlock (&rr->mutex); -			return rr->subvolume_list[i].xl; -		} -	} -   -	for (i = 0; i < next_schedule_index; i++) -	{ -		if (rr->subvolume_list[i].status == RR_SUBVOLUME_ONLINE) -		{ -			pthread_mutex_lock (&rr->mutex); -			rr->schedule_index = i; -			pthread_mutex_unlock (&rr->mutex); -			return rr->subvolume_list[i].xl; -		} -	} -   -	return NULL; -} - -void -rr_update (xlator_t *this_xl) -{ -	rr_t *rr = NULL; -	struct timeval ctime = {0, 0}; -	int i = 0; -   -	if (this_xl == NULL) -	{ -		return ; -	} -   -	if ((rr = (rr_t *) *((long *)this_xl->private)) == NULL) -	{ -		return ; -	} -   -	if (gettimeofday (&ctime, NULL) != 0) -	{ -		return ; -	} -   -	if (ctime.tv_sec > (rr->options.refresh_interval +  -			    rr->last_stat_fetched_time.tv_sec)) -	{ -		pthread_mutex_lock (&rr->mutex); -		rr->last_stat_fetched_time = ctime; -		pthread_mutex_unlock (&rr->mutex); -       -		for (i = 0; i < rr->subvolume_count; i++) -		{ -			xlator_t *subvolume_xl = NULL; -			call_frame_t *frame = NULL; -			call_pool_t *pool = NULL; -	   -			subvolume_xl = rr->subvolume_list[i].xl; -	   -			pool = this_xl->ctx->pool; -	   -			frame = create_frame (this_xl, pool); - -			STACK_WIND_COOKIE (frame, -					   rr_update_cbk,  -					   subvolume_xl->name,  -					   subvolume_xl,  -					   subvolume_xl->mops->stats,  -					   0); -		} -	} -   -	return ; -} - -int  -rr_update_cbk (call_frame_t *frame,  -	       void *cookie,  -	       xlator_t *this_xl,  -	       int32_t op_ret,  -	       int32_t op_errno,  -	       struct xlator_stats *stats) -{ -	rr_t *rr = NULL; -	rr_subvolume_t *subvolume = NULL; -	uint8_t free_disk_percent = 0; -	int i = 0; -   -	if (frame == NULL) -	{ -		return -1; -	} -   -	if (cookie == NULL || this_xl == NULL) -	{ -		STACK_DESTROY (frame->root); -		return -1; -	} -   -	if (op_ret == 0 && stats == NULL) -	{ -		LOG_CRITICAL ("fatal! op_ret is 0 and stats is NULL.  " -			      "Please report this to <gluster-devel@nongnu.org>"); -		STACK_DESTROY (frame->root); -		return -1; -	} -   -	if ((rr = (rr_t *) *((long *)this_xl->private)) == NULL) -	{ -		STACK_DESTROY (frame->root); -		return -1; -	} -   -	for (i = 0; i < rr->subvolume_count; i++) -	{ -		if (rr->subvolume_list[i].xl->name == (char *) cookie) -		{ -			subvolume = &rr->subvolume_list[i]; -			break; -		} -	} -   -	if (subvolume == NULL) -	{ -		LOG_ERROR ("unknown cookie [%s]", (char *) cookie); -		STACK_DESTROY (frame->root); -		return -1; -	} -   -	if (op_ret == 0) -	{ -		free_disk_percent = (stats->free_disk * 100) / stats->total_disk_size; -		if (free_disk_percent > rr->options.min_free_disk) -		{ -			if (subvolume->free_disk_status != RR_MIN_FREE_DISK_NOT_REACHED) -			{ -				pthread_mutex_lock (&rr->mutex); -				subvolume->free_disk_status = RR_MIN_FREE_DISK_NOT_REACHED; -				pthread_mutex_unlock (&rr->mutex); -				LOG_WARNING ("subvolume [%s] is available with free space for scheduling",  -					     subvolume->xl->name); -			} -		} -		else -		{ -			if (subvolume->free_disk_status != RR_MIN_FREE_DISK_REACHED) -			{ -				pthread_mutex_lock (&rr->mutex); -				subvolume->free_disk_status = RR_MIN_FREE_DISK_REACHED; -				pthread_mutex_unlock (&rr->mutex); -				LOG_WARNING ("subvolume [%s] reached minimum disk space requirement",  -					     subvolume->xl->name); -			} -		} -	} -	else  -	{ -		pthread_mutex_lock (&rr->mutex); -		subvolume->status = RR_SUBVOLUME_OFFLINE; -		pthread_mutex_unlock (&rr->mutex); -		LOG_ERROR ("unable to get subvolume [%s] status information and " -			   "scheduling is disabled",  -			   subvolume->xl->name); -	} -   -	STACK_DESTROY (frame->root); -	return 0; -} - -void -rr_notify (xlator_t *this_xl, int32_t event, void *data) -{ -	rr_t *rr = NULL; -	rr_subvolume_t *subvolume = NULL; -	xlator_t *subvolume_xl = NULL; -	int i = 0, ret = 0; -	call_frame_t *frame = NULL; -	call_pool_t *pool = NULL; -	dict_t *xattr = get_new_dict (); -	int32_t version[1] = {1}; - -	if (this_xl == NULL || data == NULL) { -		return ; -	} -   -	if ((rr = (rr_t *) *((long *)this_xl->private)) == NULL) { -		return ; -	} -   -	subvolume_xl = (xlator_t *) data; -   -	for (i = 0; i < rr->subvolume_count; i++) { -		if (rr->subvolume_list[i].xl == subvolume_xl) { -			subvolume = &rr->subvolume_list[i]; -			break; -		} -	} -   -	switch (event) { -	case GF_EVENT_CHILD_UP: -		/* Seeding, to be done only once */ -		if (rr->first_time && (i == rr->subvolume_count)) { -			loc_t loc = {0,}; -			xlator_t *trav = NULL; - -			pool = this_xl->ctx->pool; -			frame = create_frame (this_xl, pool); -			ret = dict_set_bin (xattr, "trusted.glusterfs.scheduler.rr", -					    version, sizeof (int32_t)); -			if (-1 == ret) { -				gf_log (this_xl->name, GF_LOG_ERROR, "rr seed setting failed"); -			} -			if (xattr) -				dict_ref (xattr); -			 -			loc.path = gf_strdup ("/"); -			for (trav = this_xl->parents->xlator; trav; trav = trav->parents->xlator) { -				if (trav->itable) { -					loc.inode = trav->itable->root; -					break; -				} -			} -			STACK_WIND (frame, -				    rr_notify_cbk, -				    (xlator_t *)data, -				    ((xlator_t *)data)->fops->xattrop, -				    &loc, -				    GF_XATTROP_ADD_ARRAY, -				    xattr); -	   -			if (xattr) -				dict_unref (xattr); - -			rr->first_time = 0; -		} -		if (subvolume) { -			pthread_mutex_lock (&rr->mutex); -			subvolume->status = RR_SUBVOLUME_ONLINE; -			pthread_mutex_unlock (&rr->mutex); -		} -		break; -	case GF_EVENT_CHILD_DOWN: -		if (subvolume) { -			pthread_mutex_lock (&rr->mutex); -			subvolume->status = RR_SUBVOLUME_OFFLINE; -			pthread_mutex_unlock (&rr->mutex); -		} -		break; -	} -   -	return ; -} - -int  -rr_notify_cbk (call_frame_t *frame,  -	       void *cookie,  -	       xlator_t *this_xl,  -	       int32_t op_ret,  -	       int32_t op_errno, -	       dict_t *xattr) -{ -	rr_t *rr = NULL; -	int32_t *index = NULL; -	int32_t ret = -1; -	void *tmp_index_ptr = NULL; - -	if (frame == NULL)  -	{ -		return -1; -	} -   -	if ((this_xl == NULL) || (op_ret == -1)) -	{ -		STACK_DESTROY (frame->root); -		return -1; -	} -   -	if ((rr = (rr_t *) *((long *)this_xl->private)) == NULL) -	{ -		STACK_DESTROY (frame->root); -		return -1; -	} -   -	ret = dict_get_bin (xattr, "trusted.glusterfs.scheduler.rr", &tmp_index_ptr); -	index = tmp_index_ptr; -	if (ret == 0) -		rr->schedule_index = (index[0] % rr->subvolume_count); -	else -		rr->schedule_index = 0; - -	STACK_DESTROY (frame->root); -	return 0; -} - -struct sched_ops sched = { -	.init     = rr_init, -	.fini     = rr_fini, -	.update   = rr_update, -	.schedule = rr_schedule, -	.notify   = rr_notify -}; - diff --git a/scheduler/rr/src/rr.h b/scheduler/rr/src/rr.h deleted file mode 100644 index 3bd95929b61..00000000000 --- a/scheduler/rr/src/rr.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -   Copyright (c) 2006-2011 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/>. -*/ - -#ifndef _RR_H -#define _RR_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "scheduler.h" -#include <stdint.h> -#include <sys/time.h> - -struct rr_subvolume -{ -  xlator_t  *xl; -  uint8_t   free_disk_status; -  uint8_t   status; -}; -typedef struct rr_subvolume rr_subvolume_t; - -struct rr -{ -  rr_options_t    options; -  rr_subvolume_t  *subvolume_list; -  uint64_t        subvolume_count; -  uint64_t        schedule_index; -  struct timeval  last_stat_fetched_time; -  pthread_mutex_t mutex; -  char            first_time; -}; -typedef struct rr rr_t; - -int rr_init (xlator_t *this_xl); -void rr_fini (xlator_t *this_xl); -xlator_t *rr_schedule (xlator_t *this_xl, const void *path); -void rr_update (xlator_t *this_xl); -int rr_update_cbk (call_frame_t *frame,  -		   void *cookie,  -		   xlator_t *this_xl,  -		   int32_t op_ret,  -		   int32_t op_errno,  -		   struct xlator_stats *stats); -void rr_notify (xlator_t *this_xl, int32_t event, void *data); -int rr_notify_cbk (call_frame_t *frame,  -		   void *cookie,  -		   xlator_t *this_xl,  -		   int32_t op_ret,  -		   int32_t op_errno, -		   dict_t *xattr); - -#endif /* _RR_H */ diff --git a/scheduler/switch/Makefile.am b/scheduler/switch/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/scheduler/switch/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/scheduler/switch/src/Makefile.am b/scheduler/switch/src/Makefile.am deleted file mode 100644 index dc7d16d40d2..00000000000 --- a/scheduler/switch/src/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -sched_LTLIBRARIES = switch.la -scheddir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler - -switch_la_LDFLAGS = -module -avoidversion - -switch_la_SOURCES = switch.c -switch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) - -CLEANFILES =  diff --git a/scheduler/switch/src/switch-mem-types.h b/scheduler/switch/src/switch-mem-types.h deleted file mode 100644 index 7039b035d0f..00000000000 --- a/scheduler/switch/src/switch-mem-types.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -   Copyright (c) 2008-2011 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/>. -*/ - - -#ifndef __SWITCH_MEM_TYPES_H__ -#define __SWITCH_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_switch_mem_types_ { -        gf_switch_mt_switch_struct = gf_common_mt_end + 1, -        gf_switch_mt_switch_sched_struct, -        gf_switch_mt_switch_sched_array, -        gf_switch_mt_end -}; -#endif - diff --git a/scheduler/switch/src/switch.c b/scheduler/switch/src/switch.c deleted file mode 100644 index 1362e5cc994..00000000000 --- a/scheduler/switch/src/switch.c +++ /dev/null @@ -1,451 +0,0 @@ -/* -  Copyright (c) 2006-2011 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 <sys/time.h> -#include <stdlib.h> -#include <fnmatch.h> - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "xlator.h" -#include "scheduler.h" -#include "switch-mem-types.h" - -struct switch_sched_array { -	xlator_t *xl; -	int32_t   eligible; -	int32_t   considered; -}; - -/* Select one of this struct based on the path's pattern match */ -struct switch_sched_struct { -	struct switch_sched_struct *next; -	struct switch_sched_array  *array; -	char                        path_pattern[256]; -	int32_t                     node_index; /* Index of the node in  -						   this pattern. */ -	int32_t                     num_child;  /* Total num of child nodes  -						   with this pattern. */ -}; - -struct switch_struct { -	struct switch_sched_struct *cond; -	struct switch_sched_array  *array; -	pthread_mutex_t             switch_mutex; -	int32_t                     child_count; -}; - -/* This function should return child node as '*:subvolumes' is inserterd */ -static xlator_t * -switch_get_matching_xl (const char *path, struct switch_sched_struct *cond) -{ -	struct switch_sched_struct *trav      = cond; -	char                       *pathname  = gf_strdup (path); -	int                         index     = 0; - -	while (trav) { -		if (fnmatch (trav->path_pattern,  -			     pathname, FNM_NOESCAPE) == 0) { -			GF_FREE (pathname); -			trav->node_index %= trav->num_child; -			index = (trav->node_index++) % trav->num_child; -			return trav->array[index].xl; -		} -		trav = trav->next; -	} -	GF_FREE (pathname); -	return NULL; -} - -static int32_t -gf_unify_valid_child (const char *child,  -                      xlator_t *xl) -{ -        xlator_list_t *children = NULL, *prev = NULL; -        int32_t  ret = 0; - -        children = xl->children; -        do { -                if (!strcmp (child, children->xlator->name)) { -                        ret = 1; -                        break; -                } -                 -                prev = children; -                children = prev->next; -        } while (children); - -        return ret; -} - -static int32_t -switch_init (xlator_t *xl) -{ -	int32_t index = 0; -	data_t *data = NULL; -	char *child = NULL; -	char *tmp = NULL; -	char *childs_data = NULL; -	xlator_list_t *trav_xl = xl->children; -	struct switch_struct *switch_buf = NULL; -   -	switch_buf = GF_CALLOC (1, sizeof (struct switch_struct), -                                gf_switch_mt_switch_struct); -	ERR_ABORT (switch_buf); - -	while (trav_xl) { -		index++; -		trav_xl = trav_xl->next; -	} -	switch_buf->child_count = index; -	switch_buf->array = GF_CALLOC (index + 1, -                                       sizeof (struct switch_sched_struct), -                                       gf_switch_mt_switch_sched_struct); -	ERR_ABORT (switch_buf->array); -	trav_xl = xl->children; -	index = 0; - -	while (trav_xl) { -		switch_buf->array[index].xl = trav_xl->xlator; -		switch_buf->array[index].eligible = 1; -		trav_xl = trav_xl->next; -		index++; -	} - -	data = dict_get (xl->options, "scheduler.read-only-subvolumes"); -	if (data) { -		childs_data = gf_strdup (data->data); -		child = strtok_r (childs_data, ",", &tmp); -		while (child) { -			for (index = 1;  -			     index < switch_buf->child_count; index++) { -				if (strcmp (switch_buf->array[index - 1].xl->name, child) == 0) { -					gf_log ("switch", GF_LOG_DEBUG,  -						"Child '%s' is read-only",  -						child); -					memcpy (&(switch_buf->array[index-1]), -						&(switch_buf->array[switch_buf->child_count - 1]),  -						sizeof (struct switch_sched_array)); -					switch_buf->child_count--; -					break; -				} -			} -			child = strtok_r (NULL, ",", &tmp); -		} -		GF_FREE (childs_data); -	} - -	data = dict_get (xl->options, "scheduler.local-volume-name"); -	if (data) { -		/* Means, give preference to that node first */ -		gf_log ("switch", GF_LOG_DEBUG,  -			"local volume defined as %s", data->data); - -		/* TODO: parse it properly, have an extra index to  -		   specify that first */ -	} - -	/*  *jpg:child1,child2;*mpg:child3;*:child4,child5,child6 */ -	data = dict_get (xl->options, "scheduler.switch.case"); -	if (data) { -		char *tmp_str = NULL;  -		char *tmp_str1 = NULL; -		char *dup_str = NULL; -		char *switch_str = NULL; -		char *pattern = NULL; -		char *childs = NULL; -		struct switch_sched_struct *switch_opt = NULL; -		struct switch_sched_struct *trav = NULL; -		/* Get the pattern for considering switch case.  -		   "option block-size *avi:10MB" etc */ -		switch_str = strtok_r (data->data, ";", &tmp_str); -		while (switch_str) { -			dup_str = gf_strdup (switch_str); -			switch_opt =  -				GF_CALLOC (1, sizeof (struct switch_sched_struct), gf_switch_mt_switch_sched_struct); -			ERR_ABORT (switch_opt); - -			/* Link it to the main structure */ -			if (switch_buf->cond) { -				/* there are already few entries */ -				trav = switch_buf->cond; -				while (trav->next) -					trav = trav->next; -				trav->next = switch_opt; -			} else { -				/* First entry */ -				switch_buf->cond = switch_opt; -			} -			pattern = strtok_r (dup_str, ":", &tmp_str1); -			childs = strtok_r (NULL, ":", &tmp_str1); -			if (strncmp (pattern, "*", 2) == 0) { -				gf_log ("switch", GF_LOG_WARNING, -					"'*' pattern will be taken by default " -					"for all the unconfigured child nodes," -					" hence neglecting current option"); -				switch_str = strtok_r (NULL, ";", &tmp_str); -				GF_FREE (dup_str); -				continue; -			} -			memcpy (switch_opt->path_pattern,  -				pattern, strlen (pattern)); -			if (childs) { -				int32_t idx = 0; -				char *tmp1 = NULL; -				char *dup_childs = NULL; -				/* TODO: get the list of child nodes for  -				   the given pattern */ -				dup_childs = gf_strdup (childs); -				child = strtok_r (dup_childs, ",", &tmp); -				while (child) { -                                        if (gf_unify_valid_child (child, xl)) { -                                                idx++; -                                                child = strtok_r (NULL, ",", &tmp); -                                        } else { -                                                gf_log ("switch", GF_LOG_ERROR, -                                                        "%s is not a subvolume " -                                                        "of %s. pattern can " -                                                        "only be scheduled only" -                                                        " to a subvolume of %s", -                                                        child, xl->name, -                                                        xl->name); -                                                return -1; -                                        } -				} -				GF_FREE (dup_childs); -				child = strtok_r (childs, ",", &tmp1); -				switch_opt->num_child = idx; -				switch_opt->array =  -					GF_CALLOC (1, idx * sizeof (struct switch_sched_array), gf_switch_mt_switch_sched_array); -				ERR_ABORT (switch_opt->array); -				idx = 0; -				child = strtok_r (childs, ",", &tmp); -				while (child) { -					for (index = 1;  -					     index < switch_buf->child_count;  -					     index++) { -						if (strcmp (switch_buf->array[index - 1].xl->name,  -							    child) == 0) { -							gf_log ("switch",  -								GF_LOG_DEBUG, -								"'%s' pattern will be scheduled to \"%s\"", -								switch_opt->path_pattern, child); -							/* -							  if (switch_buf->array[index-1].considered) { -							  gf_log ("switch", GF_LOG_DEBUG,  -							  "ambiguity found, exiting"); -							  return -1; -							  } -							*/ -							switch_opt->array[idx].xl = switch_buf->array[index-1].xl; -							switch_buf->array[index-1].considered = 1; -							idx++; -							break; -						} -					} -					child = strtok_r (NULL, ",", &tmp1); -				} -			} else { -				/* error */ -				gf_log ("switch", GF_LOG_ERROR,  -					"Check \"scheduler.switch.case\" " -					"option in unify volume. Exiting"); -				GF_FREE (switch_buf->array); -				GF_FREE (switch_buf); -				return -1; -			} -			GF_FREE (dup_str); -			switch_str = strtok_r (NULL, ";", &tmp_str); -		} -	} -	/* Now, all the pattern based considerations done, so for all the  -	 * remaining pattern, '*' to all the remaining child nodes -	 */ -	{ -		struct switch_sched_struct *switch_opt = NULL; -		int32_t flag = 0; -		int32_t index = 0; -		for (index=0; index < switch_buf->child_count; index++) { -			/* check for considered flag */ -			if (switch_buf->array[index].considered) -				continue; -			flag++; -		} -		if (!flag) { -			gf_log ("switch", GF_LOG_ERROR, -				"No nodes left for pattern '*'. Exiting."); -			return -1; -		} -		switch_opt = GF_CALLOC (1, sizeof (struct switch_sched_struct), gf_switch_mt_switch_sched_struct); -		ERR_ABORT (switch_opt); -		if (switch_buf->cond) { -			/* there are already few entries */ -			struct switch_sched_struct *trav = switch_buf->cond; -			while (trav->next) -				trav = trav->next; -			trav->next = switch_opt; -		} else { -			/* First entry */ -			switch_buf->cond = switch_opt; -		} -		/* Add the '*' pattern to the array */ -		memcpy (switch_opt->path_pattern, "*", 2); -		switch_opt->num_child = flag; -		switch_opt->array =  -			GF_CALLOC (1, flag * sizeof (struct switch_sched_array), gf_switch_mt_switch_sched_array); -		ERR_ABORT (switch_opt->array); -		flag = 0; -		for (index=0; index < switch_buf->child_count; index++) { -			/* check for considered flag */ -			if (switch_buf->array[index].considered) -				continue; -			gf_log ("switch", GF_LOG_DEBUG, -				"'%s' pattern will be scheduled to \"%s\"", -				switch_opt->path_pattern,  -				switch_buf->array[index].xl->name); -			switch_opt->array[flag].xl =  -				switch_buf->array[index].xl; -			switch_buf->array[index].considered = 1; -			flag++; -		} -	} - -	pthread_mutex_init (&switch_buf->switch_mutex, NULL); - -	// put it at the proper place -	*((long *)xl->private) = (long)switch_buf;  - -	return 0; -} - -static void -switch_fini (xlator_t *xl) -{ -	/* TODO: free all the allocated entries */ -	struct switch_struct *switch_buf = NULL; -	switch_buf = (struct switch_struct *)*((long *)xl->private); - -	pthread_mutex_destroy (&switch_buf->switch_mutex); -	GF_FREE (switch_buf->array); -	GF_FREE (switch_buf); -} - -static xlator_t * -switch_schedule (xlator_t *xl, const void *path) -{ -	struct switch_struct *switch_buf = NULL; -	switch_buf = (struct switch_struct *)*((long *)xl->private); - -	return switch_get_matching_xl (path, switch_buf->cond); -} - - -/** - * notify - */ -void -switch_notify (xlator_t *xl, int32_t event, void *data) -{ -	/* TODO: This should be checking in switch_sched_struct */ -#if 0 -	struct switch_struct *switch_buf = NULL; -	int32_t idx = 0; - -	switch_buf = (struct switch_struct *)*((long *)xl->private); -	if (!switch_buf) -		return; - -	for (idx = 0; idx < switch_buf->child_count; idx++) { -		if (switch_buf->array[idx].xl == (xlator_t *)data) -			break; -	} - -	switch (event) -	{ -	case GF_EVENT_CHILD_UP: -	{ -		switch_buf->array[idx].eligible = 1; -	} -	break; -	case GF_EVENT_CHILD_DOWN: -	{ -		switch_buf->array[idx].eligible = 0; -	} -	break; -	default: -	{ -		; -	} -	break; -	} -#endif -} - -static void  -switch_update (xlator_t *xl) -{ -	return; -} -         -int32_t -switch_mem_acct_init (xlator_t *this) -{ -        int     ret = -1; - -        if (!this) -                return ret; - -        ret = xlator_mem_acct_init (this, gf_switch_mt_end + 1); -         -        if (ret != 0) { -                gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" -                        " failed"); -                return ret; -        } - -        return ret; -} - -struct sched_ops sched = { -	.init     = switch_init, -	.fini     = switch_fini, -	.update   = switch_update, -	.schedule = switch_schedule, -	.notify   = switch_notify, -        .mem_acct_init = switch_mem_acct_init, -}; - -struct volume_options options[] = { -	{ .key   = { "scheduler.read-only-subvolumes" , -		     "switch.read-only-subvolumes"},   -	  .type  = GF_OPTION_TYPE_ANY -	}, -	{ .key   = { "scheduler.local-volume-name", -		     "switch.nufa.local-volume-name" }, -	  .type  = GF_OPTION_TYPE_XLATOR -	}, -	{ .key   = { "scheduler.switch.case", -		     "switch.case" }, -	  .type  = GF_OPTION_TYPE_ANY -	}, -	{ .key = {NULL} } -}; diff --git a/xlators/cluster/unify/Makefile.am b/xlators/cluster/unify/Makefile.am deleted file mode 100644 index d471a3f9243..00000000000 --- a/xlators/cluster/unify/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES =  diff --git a/xlators/cluster/unify/src/Makefile.am b/xlators/cluster/unify/src/Makefile.am deleted file mode 100644 index 2a1fe837263..00000000000 --- a/xlators/cluster/unify/src/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ - -xlator_LTLIBRARIES = unify.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/legacy/cluster - -unify_la_LDFLAGS = -module -avoidversion - -unify_la_SOURCES = unify.c unify-self-heal.c -unify_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -noinst_HEADERS = unify.h - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) - -CLEANFILES =  - diff --git a/xlators/cluster/unify/src/unify-mem-types.h b/xlators/cluster/unify/src/unify-mem-types.h deleted file mode 100644 index 13c9cc1f7b3..00000000000 --- a/xlators/cluster/unify/src/unify-mem-types.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* -   Copyright (c) 2008-2011 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/>. -*/ - - -#ifndef __UNIFY_MEM_TYPES_H__ -#define __UNIFY_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_unify_mem_types_ { -        gf_unify_mt_char = gf_common_mt_end + 1, -        gf_unify_mt_int16_t, -        gf_unify_mt_xlator_t, -        gf_unify_mt_unify_private_t, -        gf_unify_mt_xlator_list_t, -        gf_unify_mt_dir_entry_t, -        gf_unify_mt_off_t, -        gf_unify_mt_int, -        gf_unify_mt_unify_self_heal_struct, -        gf_unify_mt_unify_local_t, -        gf_unify_mt_end -}; -#endif - diff --git a/xlators/cluster/unify/src/unify-self-heal.c b/xlators/cluster/unify/src/unify-self-heal.c deleted file mode 100644 index f99e4c7c360..00000000000 --- a/xlators/cluster/unify/src/unify-self-heal.c +++ /dev/null @@ -1,1239 +0,0 @@ -/* -  Copyright (c) 2007-2011 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/>. -*/ - -/** - * unify-self-heal.c :  - *   This file implements few functions which enables 'unify' translator  - *  to be consistent in its behaviour when  - *     > a node fails,  - *     > a node gets added,  - *     > a failed node comes back - *     > a new namespace server is added (ie, an fresh namespace server). - *  - *  This functionality of 'unify' will enable glusterfs to support storage - *  system failure, and maintain consistancy. This works both ways, ie, when - *  an entry (either file or directory) is found on namespace server, and not - *  on storage nodes, its created in storage nodes and vica-versa. - *  - *  The two fops, where it can be implemented are 'getdents ()' and 'lookup ()' - * - */ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "glusterfs.h" -#include "unify.h" -#include "dict.h" -#include "xlator.h" -#include "hashfn.h" -#include "logging.h" -#include "stack.h" -#include "common-utils.h" - -int32_t -unify_sh_getdents_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno, -		       dir_entry_t *entry, -		       int32_t count); - -int32_t -unify_sh_ns_getdents_cbk (call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno, -			  dir_entry_t *entry, -			  int32_t count); - -int32_t -unify_bgsh_getdents_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 dir_entry_t *entry, -			 int32_t count); - -int32_t -unify_bgsh_ns_getdents_cbk (call_frame_t *frame, -			    void *cookie, -			    xlator_t *this, -			    int32_t op_ret, -			    int32_t op_errno, -			    dir_entry_t *entry, -			    int32_t count); - -/** - * unify_local_wipe - free all the extra allocation of local->* here. - */ -static void  -unify_local_wipe (unify_local_t *local) -{ -	/* Free the strdup'd variables in the local structure */ -	if (local->name) { -		GF_FREE (local->name); -	} - -	if (local->sh_struct) { -		if (local->sh_struct->offset_list) -			GF_FREE (local->sh_struct->offset_list); - -		if (local->sh_struct->entry_list) -			GF_FREE (local->sh_struct->entry_list); - -		if (local->sh_struct->count_list) -			GF_FREE (local->sh_struct->count_list); - -		GF_FREE (local->sh_struct); -	} - -	loc_wipe (&local->loc1); -	loc_wipe (&local->loc2); -} - -int32_t  -unify_sh_setdents_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno) -{ -	int32_t callcnt = -1; -	unify_local_t *local = frame->local; -	inode_t *inode = NULL; -	dict_t *tmp_dict = NULL; -	dir_entry_t *prev, *entry, *trav; - -	LOCK (&frame->lock); -	{ -		/* if local->call_count == 0, that means, setdents on  -		 * storagenodes is still pending. -		 */ -		if (local->call_count) -			callcnt = --local->call_count; -	} -	UNLOCK (&frame->lock); - -	if (callcnt == 0) { -		if (local->sh_struct->entry_list[0]) { -			prev = entry = local->sh_struct->entry_list[0]; -			if (!entry) -				return 0; -			trav = entry->next; -			while (trav) { -				prev->next = trav->next; -				GF_FREE (trav->name); -				if (IA_ISLNK (trav->buf.ia_type)) -					GF_FREE (trav->link); -				GF_FREE (trav); -				trav = prev->next; -			} -			GF_FREE (entry); -		} - -		if (!local->flags) { -			if (local->sh_struct->count_list[0] >=  -			    UNIFY_SELF_HEAL_GETDENTS_COUNT) { -				/* count == size, that means, there are more entries -				   to read from */ -				//local->call_count = 0; -				local->sh_struct->offset_list[0] +=  -					UNIFY_SELF_HEAL_GETDENTS_COUNT; -				STACK_WIND (frame, -					    unify_sh_ns_getdents_cbk, -					    NS(this), -					    NS(this)->fops->getdents, -					    local->fd, -					    UNIFY_SELF_HEAL_GETDENTS_COUNT, -					    local->sh_struct->offset_list[0], -					    GF_GET_DIR_ONLY); -			}		 -		} else { -			inode = local->loc1.inode; -			fd_unref (local->fd); -			tmp_dict = local->dict; - -			unify_local_wipe (local); -			 -			STACK_UNWIND (frame, local->op_ret, local->op_errno,  -				      inode, &local->stbuf, local->dict, -                                      &local->oldpostparent); -			if (tmp_dict) -				dict_unref (tmp_dict); -		} -	} -   -	return 0; -} - - -int32_t -unify_sh_ns_getdents_cbk (call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno, -			  dir_entry_t *entry, -			  int32_t count) -{ -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	long index = 0; -	unsigned long final = 0; -	dir_entry_t *tmp = GF_CALLOC (1, sizeof (dir_entry_t), -                                      gf_unify_mt_dir_entry_t); -	 -	local->sh_struct->entry_list[0] = tmp; -	local->sh_struct->count_list[0] = count; -	if (entry) { -		tmp->next = entry->next; -		entry->next = NULL; -	} - -	if ((count < UNIFY_SELF_HEAL_GETDENTS_COUNT) || !entry) { -		final = 1; -	} - -	LOCK (&frame->lock); -	{ -		/* local->call_count will be '0' till now. make it 1 so, it  -		   can be UNWIND'ed for the last call. */ -		local->call_count = priv->child_count; -		if (final) -			local->flags = 1; -	} -	UNLOCK (&frame->lock); - -	for (index = 0; index < priv->child_count; index++)  -	{ -		STACK_WIND_COOKIE (frame, -				   unify_sh_setdents_cbk,  -				   (void *)index, -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->setdents, -				   local->fd, GF_SET_DIR_ONLY, -				   local->sh_struct->entry_list[0], count); -	} - -	return 0; -} - -int32_t  -unify_sh_ns_setdents_cbk (call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno) -{ -	int32_t callcnt = -1; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	long index = (long)cookie; -	dir_entry_t *prev, *entry, *trav; - -	LOCK (&frame->lock); -	{ -		if (local->sh_struct->entry_list[index]) { -			prev = entry = local->sh_struct->entry_list[index]; -			trav = entry->next; -			while (trav) { -				prev->next = trav->next; -				GF_FREE (trav->name); -				if (IA_ISLNK (trav->buf.ia_type)) -					GF_FREE (trav->link); -				GF_FREE (trav); -				trav = prev->next; -			} -			GF_FREE (entry); -		} -	} -	UNLOCK (&frame->lock); - -	if (local->sh_struct->count_list[index] <  -	    UNIFY_SELF_HEAL_GETDENTS_COUNT) { -		LOCK (&frame->lock); -		{ -			callcnt = --local->call_count; -		} -		UNLOCK (&frame->lock); -	} else { -		/* count == size, that means, there are more entries  -		   to read from */ -		local->sh_struct->offset_list[index] +=  -			UNIFY_SELF_HEAL_GETDENTS_COUNT; -		STACK_WIND_COOKIE (frame, -				   unify_sh_getdents_cbk, -				   cookie, -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->getdents, -				   local->fd, -				   UNIFY_SELF_HEAL_GETDENTS_COUNT, -				   local->sh_struct->offset_list[index], -				   GF_GET_ALL); -     -		gf_log (this->name, GF_LOG_DEBUG,  -			"readdir on (%s) with offset %"PRId64"",  -			priv->xl_array[index]->name,  -			local->sh_struct->offset_list[index]); -	} - -	if (!callcnt) { -		/* All storage nodes have done unified setdents on NS node. -		 * Now, do getdents from NS and do setdents on storage nodes. -		 */ -     -		/* sh_struct->offset_list is no longer required for -		   storage nodes now */ -		local->sh_struct->offset_list[0] = 0; /* reset */ - -		STACK_WIND (frame, -			    unify_sh_ns_getdents_cbk, -			    NS(this), -			    NS(this)->fops->getdents, -			    local->fd, -			    UNIFY_SELF_HEAL_GETDENTS_COUNT, -			    0, /* In this call, do send '0' as offset */ -			    GF_GET_DIR_ONLY); -	} - -	return 0; -} - - -/** - * unify_sh_getdents_cbk - - */ -int32_t -unify_sh_getdents_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno, -		       dir_entry_t *entry, -		       int32_t count) -{ -	int32_t callcnt = -1; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	long index = (long)cookie; -	dir_entry_t *tmp = NULL;  - -	if (op_ret >= 0 && count > 0) { -		/* There is some dentry found, just send the dentry to NS */ -		tmp = GF_CALLOC (1, sizeof (dir_entry_t), -                                 gf_unify_mt_dir_entry_t); -		local->sh_struct->entry_list[index] = tmp; -		local->sh_struct->count_list[index] = count; -		if (entry) { -			tmp->next = entry->next; -			entry->next = NULL; -		} -		STACK_WIND_COOKIE (frame, -				   unify_sh_ns_setdents_cbk, -				   cookie, -				   NS(this), -				   NS(this)->fops->setdents, -				   local->fd, -				   GF_SET_IF_NOT_PRESENT, -				   local->sh_struct->entry_list[index], -				   count); -		return 0; -	} -   -	if (count < UNIFY_SELF_HEAL_GETDENTS_COUNT) { -		LOCK (&frame->lock); -		{ -			callcnt = --local->call_count; -		} -		UNLOCK (&frame->lock); -	} else { -		/* count == size, that means, there are more entries  -		   to read from */ -		local->sh_struct->offset_list[index] +=  -			UNIFY_SELF_HEAL_GETDENTS_COUNT; -		STACK_WIND_COOKIE (frame, -				   unify_sh_getdents_cbk, -				   cookie, -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->getdents, -				   local->fd, -				   UNIFY_SELF_HEAL_GETDENTS_COUNT, -				   local->sh_struct->offset_list[index], -				   GF_GET_ALL); -     -		gf_log (this->name, GF_LOG_DEBUG,  -			"readdir on (%s) with offset %"PRId64"",  -			priv->xl_array[index]->name,  -			local->sh_struct->offset_list[index]); -	} - -	if (!callcnt) { -		/* All storage nodes have done unified setdents on NS node. -		 * Now, do getdents from NS and do setdents on storage nodes. -		 */ -     -		/* sh_struct->offset_list is no longer required for -		   storage nodes now */ -		local->sh_struct->offset_list[0] = 0; /* reset */ - -		STACK_WIND (frame, -			    unify_sh_ns_getdents_cbk, -			    NS(this), -			    NS(this)->fops->getdents, -			    local->fd, -			    UNIFY_SELF_HEAL_GETDENTS_COUNT, -			    0, /* In this call, do send '0' as offset */ -			    GF_GET_DIR_ONLY); -	} - -	return 0; -} - -/** - * unify_sh_opendir_cbk - - * - * @cookie:  - */ -int32_t  -unify_sh_opendir_cbk (call_frame_t *frame, -		      void *cookie, -		      xlator_t *this, -		      int32_t op_ret, -		      int32_t op_errno, -		      fd_t *fd) -{ -	int32_t callcnt = 0; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	int16_t index = 0; -	inode_t *inode = NULL; -	dict_t *tmp_dict = NULL; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -     -		if (op_ret >= 0) { -			local->op_ret = op_ret; -		} else { -			gf_log (this->name, GF_LOG_WARNING, "failed"); -			local->failed = 1; -		} -	} -	UNLOCK (&frame->lock); -   -	if (!callcnt) { -		local->call_count = priv->child_count + 1; -     -		if (!local->failed) { -			/* send getdents() namespace after finishing -			   storage nodes */ -			local->call_count--;  -       -			fd_bind (fd); - -			if (local->call_count) { -				/* Used as the offset index. This list keeps -				 * track of offset sent to each node during -				 * STACK_WIND. -				 */ -				local->sh_struct->offset_list =  -					GF_CALLOC (priv->child_count,  -					           sizeof (off_t), -                                                   gf_unify_mt_off_t); -				ERR_ABORT (local->sh_struct->offset_list); -	 -				local->sh_struct->entry_list =  -					GF_CALLOC (priv->child_count,  -						   sizeof (dir_entry_t *), -                                                   gf_unify_mt_dir_entry_t); -				ERR_ABORT (local->sh_struct->entry_list); - -				local->sh_struct->count_list =  -					GF_CALLOC (priv->child_count,  -						   sizeof (int), -                                                   gf_unify_mt_int); -				ERR_ABORT (local->sh_struct->count_list); - -				/* Send getdents on all the fds */ -				for (index = 0;  -				     index < priv->child_count; index++) { -					STACK_WIND_COOKIE (frame, -							   unify_sh_getdents_cbk, -							   (void *)(long)index, -							   priv->xl_array[index], -							   priv->xl_array[index]->fops->getdents, -							   local->fd, -							   UNIFY_SELF_HEAL_GETDENTS_COUNT, -							   0, /* In this call, do send '0' as offset */ -							   GF_GET_ALL); -				} - -				/* did stack wind, so no need to unwind here */ -				return 0; -			} /* (local->call_count) */ -		} /* (!local->failed) */ - -		/* Opendir failed on one node. */  -		inode = local->loc1.inode; -		fd_unref (local->fd); -		tmp_dict = local->dict; - -		unify_local_wipe (local); -		/* Only 'self-heal' failed, lookup() was successful. */ -		local->op_ret = 0; - -		/* This is lookup_cbk ()'s UNWIND. */ -		STACK_UNWIND (frame, local->op_ret, local->op_errno, inode, -			      &local->stbuf, local->dict, &local->oldpostparent); -		if (tmp_dict) -			dict_unref (tmp_dict); -	} - -	return 0; -} - -/** - * gf_sh_checksum_cbk -  - *  - * @frame: frame used in lookup. get a copy of it, and use that copy. - * @this: pointer to unify xlator. - * @inode: pointer to inode, for which the consistency check is required. - * - */ -int32_t  -unify_sh_checksum_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno, -		       uint8_t *file_checksum, -		       uint8_t *dir_checksum) -{ -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	int16_t index = 0; -	int32_t callcnt = 0; -	inode_t *inode = NULL; -	dict_t *tmp_dict = NULL; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -		if (op_ret >= 0) { -			if (NS(this) == (xlator_t *)cookie) { -				memcpy (local->sh_struct->ns_file_checksum,  -					file_checksum, NAME_MAX); -				memcpy (local->sh_struct->ns_dir_checksum,  -					dir_checksum, NAME_MAX); -			} else { -				if (local->entry_count == 0) { -					/* Initialize the dir_checksum to be  -					 * used for comparision with other -					 * storage nodes. Should be done for -					 * the first successful call *only*.  -					 */ -                                        /* Using 'entry_count' as a flag */ -					local->entry_count = 1; -					memcpy (local->sh_struct->dir_checksum, -						dir_checksum, NAME_MAX); -				} - -				/* Reply from the storage nodes */ -				for (index = 0;  -				     index < NAME_MAX; index++) { -					/* Files should be present in -					   only one node */ -					local->sh_struct->file_checksum[index] ^= file_checksum[index]; -	   -					/* directory structure should be -					   same accross */ -					if (local->sh_struct->dir_checksum[index] != dir_checksum[index]) -						local->failed = 1; -				} -			} -		}  -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		for (index = 0; index < NAME_MAX ; index++) { -			if (local->sh_struct->file_checksum[index] !=  -			    local->sh_struct->ns_file_checksum[index]) { -				local->failed = 1; -				break; -			} -			if (local->sh_struct->dir_checksum[index] !=  -			    local->sh_struct->ns_dir_checksum[index]) { -				local->failed = 1; -				break; -			} -		} -	 -		if (local->failed) { -			/* Log it, it should be a rare event */ -			gf_log (this->name, GF_LOG_WARNING,  -				"Self-heal triggered on directory %s",  -				local->loc1.path); - -			/* Any self heal will be done at directory level */ -			local->call_count = 0; -			local->op_ret = -1; -			local->failed = 0; -       -			local->fd = fd_create (local->loc1.inode,  -					       frame->root->pid); - -			local->call_count = priv->child_count + 1; -	 -			for (index = 0;  -			     index < (priv->child_count + 1); index++) { -				STACK_WIND_COOKIE (frame, -						   unify_sh_opendir_cbk, -						   priv->xl_array[index]->name, -						   priv->xl_array[index], -						   priv->xl_array[index]->fops->opendir, -						   &local->loc1, -						   local->fd); -			} -			/* opendir can be done on the directory */ -			return 0; -		} - -		/* no mismatch */ -		inode = local->loc1.inode; -		tmp_dict = local->dict; - -		unify_local_wipe (local); - -		/* This is lookup_cbk ()'s UNWIND. */ -		STACK_UNWIND (frame, -			      local->op_ret, -			      local->op_errno, -			      inode, -			      &local->stbuf, -			      local->dict, &local->oldpostparent); -		if (tmp_dict) -			dict_unref (tmp_dict); -	} - -	return 0; -} - -/* Foreground self-heal part over */ - -/* Background self-heal part */ - -int32_t  -unify_bgsh_setdents_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno) -{ -	int32_t callcnt = -1; -	unify_local_t *local = frame->local; -	dir_entry_t *prev, *entry, *trav; - -	LOCK (&frame->lock); -	{ -		/* if local->call_count == 0, that means, setdents  -		   on storagenodes is still pending. */ -		if (local->call_count) -			callcnt = --local->call_count; -	} -	UNLOCK (&frame->lock); - - -	if (callcnt == 0) { -		if (local->sh_struct->entry_list[0]) { -			prev = entry = local->sh_struct->entry_list[0]; -			trav = entry->next; -			while (trav) { -				prev->next = trav->next; -				GF_FREE (trav->name); -				if (IA_ISLNK (trav->buf.ia_type)) -					GF_FREE (trav->link); -				GF_FREE (trav); -				trav = prev->next; -			} -			GF_FREE (entry); -		} - -		if (!local->flags) { -			if (local->sh_struct->count_list[0] >=  -			    UNIFY_SELF_HEAL_GETDENTS_COUNT) { -				/* count == size, that means, there are more -				   entries to read from */ -				//local->call_count = 0; -				local->sh_struct->offset_list[0] +=  -					UNIFY_SELF_HEAL_GETDENTS_COUNT; -				STACK_WIND (frame, -					    unify_bgsh_ns_getdents_cbk, -					    NS(this), -					    NS(this)->fops->getdents, -					    local->fd, -					    UNIFY_SELF_HEAL_GETDENTS_COUNT, -					    local->sh_struct->offset_list[0], -					    GF_GET_DIR_ONLY); -			}		 -		} else { -			fd_unref (local->fd); -			unify_local_wipe (local); -			STACK_DESTROY (frame->root); -		} -	} - -	return 0; -} - - -int32_t -unify_bgsh_ns_getdents_cbk (call_frame_t *frame, -			    void *cookie, -			    xlator_t *this, -			    int32_t op_ret, -			    int32_t op_errno, -			    dir_entry_t *entry, -			    int32_t count) -{ -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	long index = 0; -	unsigned long final = 0; -	dir_entry_t *tmp = GF_CALLOC (1, sizeof (dir_entry_t), -                                      gf_unify_mt_dir_entry_t); - -	local->sh_struct->entry_list[0] = tmp; -	local->sh_struct->count_list[0] = count; -	if (entry) { -		tmp->next = entry->next; -		entry->next = NULL; -	} - -	if ((count < UNIFY_SELF_HEAL_GETDENTS_COUNT) || !entry) { -		final = 1; -	} - -	LOCK (&frame->lock); -	{ -		/* local->call_count will be '0' till now. make it 1 so,  -		   it can be UNWIND'ed for the last call. */ -		local->call_count = priv->child_count; -		if (final) -			local->flags = 1; -	} -	UNLOCK (&frame->lock); - -	for (index = 0; index < priv->child_count; index++)  -	{ -		STACK_WIND_COOKIE (frame, -				   unify_bgsh_setdents_cbk,  -				   (void *)index, -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->setdents, -				   local->fd, GF_SET_DIR_ONLY, -				   local->sh_struct->entry_list[0], count); -	} - -	return 0; -} - -int32_t  -unify_bgsh_ns_setdents_cbk (call_frame_t *frame, -			    void *cookie, -			    xlator_t *this, -			    int32_t op_ret, -			    int32_t op_errno) -{ -	int32_t callcnt = -1; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	long index = (long)cookie; -	dir_entry_t *prev, *entry, *trav; - -	if (local->sh_struct->entry_list[index]) { -		prev = entry = local->sh_struct->entry_list[index]; -		if (!entry) -			return 0; -		trav = entry->next; -		while (trav) { -			prev->next = trav->next; -			GF_FREE (trav->name); -			if (IA_ISLNK (trav->buf.ia_type)) -				GF_FREE (trav->link); -			GF_FREE (trav); -			trav = prev->next; -		} -		GF_FREE (entry); -	} - -	if (local->sh_struct->count_list[index] <  -	    UNIFY_SELF_HEAL_GETDENTS_COUNT) { -		LOCK (&frame->lock); -		{ -			callcnt = --local->call_count; -		} -		UNLOCK (&frame->lock); -	} else { -		/* count == size, that means, there are more entries  -		   to read from */ -		local->sh_struct->offset_list[index] +=  -			UNIFY_SELF_HEAL_GETDENTS_COUNT; -		STACK_WIND_COOKIE (frame, -				   unify_bgsh_getdents_cbk, -				   cookie, -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->getdents, -				   local->fd, -				   UNIFY_SELF_HEAL_GETDENTS_COUNT, -				   local->sh_struct->offset_list[index], -				   GF_GET_ALL); -     -		gf_log (this->name, GF_LOG_DEBUG,  -			"readdir on (%s) with offset %"PRId64"",  -			priv->xl_array[index]->name,  -			local->sh_struct->offset_list[index]); -	} - -	if (!callcnt) { -		/* All storage nodes have done unified setdents on NS node. -		 * Now, do getdents from NS and do setdents on storage nodes. -		 */ -     -		/* sh_struct->offset_list is no longer required for -		   storage nodes now */ -		local->sh_struct->offset_list[0] = 0; /* reset */ - -		STACK_WIND (frame, -			    unify_bgsh_ns_getdents_cbk, -			    NS(this), -			    NS(this)->fops->getdents, -			    local->fd, -			    UNIFY_SELF_HEAL_GETDENTS_COUNT, -			    0, /* In this call, do send '0' as offset */ -			    GF_GET_DIR_ONLY); -	} - -	return 0; -} - - -/** - * unify_bgsh_getdents_cbk - - */ -int32_t -unify_bgsh_getdents_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 dir_entry_t *entry, -			 int32_t count) -{ -	int32_t callcnt = -1; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	long index = (long)cookie; -	dir_entry_t *tmp = NULL;  - -	if (op_ret >= 0 && count > 0) { -		/* There is some dentry found, just send the dentry to NS */ -		tmp = GF_CALLOC (1, sizeof (dir_entry_t), -                                 gf_unify_mt_dir_entry_t); -		local->sh_struct->entry_list[index] = tmp; -		local->sh_struct->count_list[index] = count; -		if (entry) { -			tmp->next = entry->next; -			entry->next = NULL; -		} -		STACK_WIND_COOKIE (frame, -				   unify_bgsh_ns_setdents_cbk, -				   cookie, -				   NS(this), -				   NS(this)->fops->setdents, -				   local->fd, -				   GF_SET_IF_NOT_PRESENT, -				   local->sh_struct->entry_list[index], -				   count); -		return 0; -	} -   -	if (count < UNIFY_SELF_HEAL_GETDENTS_COUNT) { -		LOCK (&frame->lock); -		{ -			callcnt = --local->call_count; -		} -		UNLOCK (&frame->lock); -	} else { -		/* count == size, that means, there are more entries to read from */ -		local->sh_struct->offset_list[index] +=  -			UNIFY_SELF_HEAL_GETDENTS_COUNT; - -		STACK_WIND_COOKIE (frame, -				   unify_bgsh_getdents_cbk, -				   cookie, -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->getdents, -				   local->fd, -				   UNIFY_SELF_HEAL_GETDENTS_COUNT, -				   local->sh_struct->offset_list[index], -				   GF_GET_ALL); -     -		gf_log (this->name, GF_LOG_DEBUG,  -			"readdir on (%s) with offset %"PRId64"",  -			priv->xl_array[index]->name,  -			local->sh_struct->offset_list[index]); -	} - -	if (!callcnt) { -		/* All storage nodes have done unified setdents on NS node. -		 * Now, do getdents from NS and do setdents on storage nodes. -		 */ -     -		/* sh_struct->offset_list is no longer required for  -		   storage nodes now */ -		local->sh_struct->offset_list[0] = 0; /* reset */ - -		STACK_WIND (frame, -			    unify_bgsh_ns_getdents_cbk, -			    NS(this), -			    NS(this)->fops->getdents, -			    local->fd, -			    UNIFY_SELF_HEAL_GETDENTS_COUNT, -			    0, /* In this call, do send '0' as offset */ -			    GF_GET_DIR_ONLY); -	} - -	return 0; -} - -/** - * unify_bgsh_opendir_cbk - - * - * @cookie:  - */ -int32_t  -unify_bgsh_opendir_cbk (call_frame_t *frame, -			void *cookie, -			xlator_t *this, -			int32_t op_ret, -			int32_t op_errno, -			fd_t *fd) -{ -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	int32_t callcnt = 0; -	int16_t index = 0; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -     -		if (op_ret >= 0) { -			local->op_ret = op_ret; -		} else { -			local->failed = 1; -		} -	} -	UNLOCK (&frame->lock); -   -	if (!callcnt) { -		local->call_count = priv->child_count + 1; -     -		if (!local->failed) { -			/* send getdents() namespace after finishing  -			   storage nodes */ -			local->call_count--;  -			callcnt = local->call_count; -       -			fd_bind (fd); - -			if (local->call_count) { -				/* Used as the offset index. This list keeps  -				   track of offset sent to each node during  -				   STACK_WIND. */ -				local->sh_struct->offset_list =  -					GF_CALLOC (priv->child_count,  -					           sizeof (off_t), -                                                   gf_unify_mt_off_t); -				ERR_ABORT (local->sh_struct->offset_list); -	 -				local->sh_struct->entry_list =  -					GF_CALLOC (priv->child_count,  -						   sizeof (dir_entry_t *), -                                                   gf_unify_mt_dir_entry_t); -				ERR_ABORT (local->sh_struct->entry_list); - -				local->sh_struct->count_list =  -					GF_CALLOC (priv->child_count,  -						   sizeof (int), -                                                   gf_unify_mt_int); -				ERR_ABORT (local->sh_struct->count_list); - -				/* Send getdents on all the fds */ -				for (index = 0;  -				     index < priv->child_count; index++) { -					STACK_WIND_COOKIE (frame, -							   unify_bgsh_getdents_cbk, -							   (void *)(long)index, -							   priv->xl_array[index], -							   priv->xl_array[index]->fops->getdents, -							   local->fd, -							   UNIFY_SELF_HEAL_GETDENTS_COUNT, -							   0, /* In this call, do send '0' as offset */ -							   GF_GET_ALL); -				} -				/* did a stack wind, so no need to unwind here */ -				return 0; -			} /* (local->call_count) */ -		} /* (!local->failed) */ - -		/* Opendir failed on one node. 	 */ -		fd_unref (local->fd); -		 -		unify_local_wipe (local); -		STACK_DESTROY (frame->root); -	} - -	return 0; -} - -/** - * gf_bgsh_checksum_cbk -  - *  - * @frame: frame used in lookup. get a copy of it, and use that copy. - * @this: pointer to unify xlator. - * @inode: pointer to inode, for which the consistency check is required. - * - */ -int32_t  -unify_bgsh_checksum_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 uint8_t *file_checksum, -			 uint8_t *dir_checksum) -{ -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	int16_t index = 0; -	int32_t callcnt = 0; -   -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -		if (op_ret >= 0) { -			if (NS(this) == (xlator_t *)cookie) { -				memcpy (local->sh_struct->ns_file_checksum,  -					file_checksum, NAME_MAX); -				memcpy (local->sh_struct->ns_dir_checksum,  -					dir_checksum, NAME_MAX); -			} else { -				if (local->entry_count == 0) { -					/* Initialize the dir_checksum to be  -					 * used for comparision with other  -					 * storage nodes. Should be done for -					 * the first successful call *only*.  -					 */ -					/* Using 'entry_count' as a flag */ -					local->entry_count = 1;  -					memcpy (local->sh_struct->dir_checksum, -						dir_checksum, NAME_MAX); -				} - -				/* Reply from the storage nodes */ -				for (index = 0;  -				     index < NAME_MAX; index++) { -					/* Files should be present in only  -					   one node */ -					local->sh_struct->file_checksum[index] ^= file_checksum[index]; -	   -					/* directory structure should be same  -					   accross */ -					if (local->sh_struct->dir_checksum[index] != dir_checksum[index]) -						local->failed = 1; -				} -			} -		}  -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		for (index = 0; index < NAME_MAX ; index++) { -			if (local->sh_struct->file_checksum[index] !=  -			    local->sh_struct->ns_file_checksum[index]) { -				local->failed = 1; -				break; -			} -			if (local->sh_struct->dir_checksum[index] !=  -			    local->sh_struct->ns_dir_checksum[index]) { -				local->failed = 1; -				break; -			} -		} -	 -		if (local->failed) { -			/* Log it, it should be a rare event */ -			gf_log (this->name, GF_LOG_WARNING,  -				"Self-heal triggered on directory %s",  -				local->loc1.path); - -			/* Any self heal will be done at the directory level */ -			local->op_ret = -1; -			local->failed = 0; -       -			local->fd = fd_create (local->loc1.inode,  -					       frame->root->pid); -			local->call_count = priv->child_count + 1; -	 -			for (index = 0;  -			     index < (priv->child_count + 1); index++) { -				STACK_WIND_COOKIE (frame, -						   unify_bgsh_opendir_cbk, -						   priv->xl_array[index]->name, -						   priv->xl_array[index], -						   priv->xl_array[index]->fops->opendir, -						   &local->loc1, -						   local->fd); -			} -       -			/* opendir can be done on the directory */ -			return 0; -		} - -		/* no mismatch */ -		unify_local_wipe (local); -		STACK_DESTROY (frame->root); -	} - -	return 0; -} - -/* Background self-heal part over */ - - - - -/** - * zr_unify_self_heal -  - *  - * @frame: frame used in lookup. get a copy of it, and use that copy. - * @this: pointer to unify xlator. - * @inode: pointer to inode, for which the consistency check is required. - * - */ -int32_t  -zr_unify_self_heal (call_frame_t *frame, -		    xlator_t *this, -		    unify_local_t *local) -{ -	unify_private_t *priv = this->private; -	call_frame_t *bg_frame = NULL; -	unify_local_t *bg_local = NULL; -	inode_t *tmp_inode = NULL; -	dict_t *tmp_dict = NULL; -	int16_t index = 0; -   -	if (local->inode_generation < priv->inode_generation) { -		/* Any self heal will be done at the directory level */ -		/* Update the inode's generation to the current generation -		   value. */ -		local->inode_generation = priv->inode_generation; -		inode_ctx_put (local->loc1.inode, this,  -			  (uint64_t)(long)local->inode_generation); - -		if (priv->self_heal == ZR_UNIFY_FG_SELF_HEAL) { -			local->op_ret = 0; -			local->failed = 0; -			local->call_count = priv->child_count + 1; -			local->sh_struct =  -	         	     GF_CALLOC (1, sizeof (struct unify_self_heal_struct), -                                        gf_unify_mt_unify_self_heal_struct); -       -			/* +1 is for NS */ -			for (index = 0;  -			     index < (priv->child_count + 1); index++) { -				STACK_WIND_COOKIE (frame, -						   unify_sh_checksum_cbk, -						   priv->xl_array[index], -						   priv->xl_array[index], -						   priv->xl_array[index]->fops->checksum, -						   &local->loc1, -						   0); -			} - -			/* Self-heal in foreground, hence no need  -			   to UNWIND here */ -			return 0; -		} - -		/* Self Heal done in background */ -		bg_frame = copy_frame (frame); -		INIT_LOCAL (bg_frame, bg_local); -		loc_copy (&bg_local->loc1, &local->loc1); -		bg_local->op_ret = 0; -		bg_local->failed = 0; -		bg_local->call_count = priv->child_count + 1; -		bg_local->sh_struct =  -			GF_CALLOC (1, sizeof (struct unify_self_heal_struct), -                                   gf_unify_mt_unify_self_heal_struct); -     -		/* +1 is for NS */ -		for (index = 0; index < (priv->child_count + 1); index++) { -			STACK_WIND_COOKIE (bg_frame, -					   unify_bgsh_checksum_cbk, -					   priv->xl_array[index], -					   priv->xl_array[index], -					   priv->xl_array[index]->fops->checksum, -					   &bg_local->loc1, -					   0); -		} -	} - -	/* generation number matches, self heal already done or -	 * self heal done in background: just do STACK_UNWIND  -	 */ -	tmp_inode = local->loc1.inode; -	tmp_dict = local->dict; - -	unify_local_wipe (local); - -	/* This is lookup_cbk ()'s UNWIND. */ -	STACK_UNWIND (frame, -		      local->op_ret, -		      local->op_errno, -		      tmp_inode, -		      &local->stbuf, -		      local->dict, -                      &local->oldpostparent); - -	if (tmp_dict) -		dict_unref (tmp_dict); - -	return 0; -} - diff --git a/xlators/cluster/unify/src/unify.c b/xlators/cluster/unify/src/unify.c deleted file mode 100644 index f3da6d0bac7..00000000000 --- a/xlators/cluster/unify/src/unify.c +++ /dev/null @@ -1,4589 +0,0 @@ -/* -  Copyright (c) 2006-2011 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/>. -*/ - -/** - * xlators/cluster/unify: - *     - This xlator is one of the main translator in GlusterFS, which - *   actually does the clustering work of the file system. One need to  - *   understand that, unify assumes file to be existing in only one of  - *   the child node, and directories to be present on all the nodes.  - * - * NOTE: - *   Now, unify has support for global namespace, which is used to keep a  - * global view of fs's namespace tree. The stat for directories are taken - * just from the namespace, where as for files, just 'ia_ino' is taken from - * Namespace node, and other stat info is taken from the actual storage node. - * Also Namespace node helps to keep consistant inode for files across  - * glusterfs (re-)mounts. - */ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "glusterfs.h" -#include "unify.h" -#include "dict.h" -#include "xlator.h" -#include "hashfn.h" -#include "logging.h" -#include "stack.h" -#include "defaults.h" -#include "common-utils.h" -#include <signal.h> -#include <libgen.h> -#include "compat-errno.h" -#include "compat.h" - -#define UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR(_loc) do { \ -  if (!(_loc && _loc->inode)) {                            \ -    STACK_UNWIND (frame, -1, EINVAL, NULL, NULL, NULL);    \ -    return 0;                                              \ -  }                                                        \ -} while(0) - - -#define UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR(_fd) do { \ -  if (!(_fd && !fd_ctx_get (_fd, this, NULL))) {       \ -    STACK_UNWIND (frame, -1, EBADFD, NULL, NULL);      \ -    return 0;                                          \ -  }                                                    \ -} while(0) - -#define UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(_fd) do { \ -  if (!_fd) {                                      \ -    STACK_UNWIND (frame, -1, EBADFD, NULL, NULL);  \ -    return 0;                                      \ -  }                                                \ -} while(0) - -/** - * unify_local_wipe - free all the extra allocation of local->* here. - */ -static void  -unify_local_wipe (unify_local_t *local) -{ -	/* Free the strdup'd variables in the local structure */ -	if (local->name) { -		GF_FREE (local->name); -	} -	loc_wipe (&local->loc1); -	loc_wipe (&local->loc2); -} - - - -/* - * unify_normalize_stats - - */ -void -unify_normalize_stats (struct statvfs *buf, -		       unsigned long bsize, -		       unsigned long frsize) -{ -	double factor; - -	if (buf->f_bsize != bsize) { -		factor = ((double) buf->f_bsize) / bsize; -		buf->f_bsize  = bsize; -		buf->f_bfree  = (fsblkcnt_t) (factor * buf->f_bfree); -		buf->f_bavail = (fsblkcnt_t) (factor * buf->f_bavail); -	} -   -	if (buf->f_frsize != frsize) { -		factor = ((double) buf->f_frsize) / frsize; -		buf->f_frsize = frsize; -		buf->f_blocks = (fsblkcnt_t) (factor * buf->f_blocks); -	} -} - - -xlator_t * -unify_loc_subvol (loc_t *loc, xlator_t *this) -{ -	unify_private_t *priv = NULL; -	xlator_t        *subvol = NULL; -	int16_t         *list = NULL; -	long             index = 0; -	xlator_t        *subvol_i = NULL; -	int              ret = 0; -	uint64_t         tmp_list = 0; - -	priv   = this->private; -	subvol = NS (this); - -	if (!IA_ISDIR (loc->inode->ia_type)) { -		ret = inode_ctx_get (loc->inode, this, &tmp_list); -		list = (int16_t *)(long)tmp_list; -		if (!list) -			goto out; - -		for (index = 0; list[index] != -1; index++) { -			subvol_i = priv->xl_array[list[index]]; -			if (subvol_i != NS (this)) { -				subvol = subvol_i; -				break; -			} -		} -	} -out: -	return subvol; -} - - - -/** - * unify_statfs_cbk - - */ -int32_t -unify_statfs_cbk (call_frame_t *frame, -		  void *cookie, -		  xlator_t *this, -		  int32_t op_ret, -		  int32_t op_errno, -		  struct statvfs *stbuf) -{ -	int32_t callcnt = 0; -	struct statvfs *dict_buf = NULL; -	unsigned long bsize; -	unsigned long frsize; -	unify_local_t *local = (unify_local_t *)frame->local; -	call_frame_t *prev_frame = cookie; - -	LOCK (&frame->lock); -	{ -		if (op_ret >= 0) { -			/* when a call is successfull, add it to local->dict */ -			dict_buf = &local->statvfs_buf; - -			if (dict_buf->f_bsize != 0) { -				bsize  = max (dict_buf->f_bsize,  -					      stbuf->f_bsize); - -				frsize = max (dict_buf->f_frsize,  -					      stbuf->f_frsize); -				unify_normalize_stats(dict_buf, bsize, frsize); -				unify_normalize_stats(stbuf, bsize, frsize); -			} else { -				dict_buf->f_bsize   = stbuf->f_bsize; -				dict_buf->f_frsize  = stbuf->f_frsize; -			} -       -			dict_buf->f_blocks += stbuf->f_blocks; -			dict_buf->f_bfree  += stbuf->f_bfree; -			dict_buf->f_bavail += stbuf->f_bavail; -			dict_buf->f_files  += stbuf->f_files; -			dict_buf->f_ffree  += stbuf->f_ffree; -			dict_buf->f_favail += stbuf->f_favail; -			dict_buf->f_fsid    = stbuf->f_fsid; -			dict_buf->f_flag    = stbuf->f_flag; -			dict_buf->f_namemax = stbuf->f_namemax; -			local->op_ret = op_ret; -		} else { -			/* fop on storage node has failed due to some error */ -			if (op_errno != ENOTCONN) { -				gf_log (this->name, GF_LOG_ERROR,  -					"child(%s): %s",  -					prev_frame->this->name,  -					strerror (op_errno)); -			} -			local->op_errno = op_errno; -		} -		callcnt = --local->call_count; -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		STACK_UNWIND (frame, local->op_ret, local->op_errno,  -			      &local->statvfs_buf); -	} - -	return 0; -} - -/** - * unify_statfs - - */ -int32_t -unify_statfs (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *loc) -{ -	unify_local_t *local = NULL; -	xlator_list_t *trav = this->children; - -	INIT_LOCAL (frame, local); -	local->call_count = ((unify_private_t *)this->private)->child_count; - -	while(trav) { -		STACK_WIND (frame, -			    unify_statfs_cbk, -			    trav->xlator, -			    trav->xlator->fops->statfs, -			    loc); -		trav = trav->next; -	} - -	return 0; -} - -/** - * unify_buf_cbk -  - */ -int32_t -unify_buf_cbk (call_frame_t *frame, -	       void *cookie, -	       xlator_t *this, -	       int32_t op_ret, -	       int32_t op_errno, -	       struct iatt *buf) -{ -	int32_t callcnt = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -     -		if (op_ret == -1) { -			gf_log (this->name, GF_LOG_ERROR, -				"%s(): child(%s): path(%s): %s",  -				gf_fop_list[frame->root->op], -				prev_frame->this->name,  -				(local->loc1.path)?local->loc1.path:"",  -				strerror (op_errno)); - -			local->op_errno = op_errno; -			if ((op_errno == ENOENT) && priv->optimist)  -				local->op_ret = 0; -		} - -		if (op_ret >= 0) { -			local->op_ret = 0; - -			if (NS (this) == prev_frame->this) { -				local->ia_ino = buf->ia_ino; -				/* If the entry is directory, get the stat -				   from NS node */ -				if (IA_ISDIR (buf->ia_type) ||  -				    !local->stbuf.ia_blksize) { -					local->stbuf = *buf; -				} -			} - -			if ((!IA_ISDIR (buf->ia_type)) &&  -			    (NS (this) != prev_frame->this)) { -				/* If file, take the stat info from Storage  -				   node. */ -				local->stbuf = *buf; -			} -		} -	} -	UNLOCK (&frame->lock); -     -	if (!callcnt) { -		/* If the inode number is not filled, operation should -		   fail */ -		if (!local->ia_ino) -			local->op_ret = -1; - -		local->stbuf.ia_ino = local->ia_ino; -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno,  -			      &local->stbuf); -	} - -	return 0; -} - -#define check_if_dht_linkfile(s) \ -        ((st_mode_from_ia (s->ia_prot, s->ia_type) & ~S_IFMT) == S_ISVTX) - -/** - * unify_lookup_cbk -  - */ -int32_t  -unify_lookup_cbk (call_frame_t *frame, -		  void *cookie, -		  xlator_t *this, -		  int32_t op_ret, -		  int32_t op_errno, -		  inode_t *inode, -		  struct iatt *buf, -		  dict_t *dict, -                  struct iatt *postparent) -{ -	int32_t callcnt = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	inode_t *tmp_inode = NULL; -	dict_t *local_dict = NULL; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -  -		if (op_ret == -1) { -                        if (local->revalidate && -                            (op_errno == ESTALE)) { -                                /* ESTALE takes priority */ -                                local->op_errno = op_errno; -                                local->failed = 1; -                        } - -			if ((op_errno != ENOTCONN)  -                            && (op_errno != ENOENT) -                            && (local->op_errno != ESTALE)) { -                                /* if local->op_errno is already ESTALE, then -                                 * ESTALE has to propogated to the parent first. -                                 * do not enter here. -                                 */ -				gf_log (this->name, GF_LOG_ERROR, -					"child(%s): path(%s): %s",  -					priv->xl_array[(long)cookie]->name,  -					local->loc1.path, strerror (op_errno)); -                                local->op_errno = op_errno; -				local->failed = 1; - -			} else if (local->revalidate &&  -                                   (local->op_errno != ESTALE) && -				   !(priv->optimist && (op_errno == ENOENT))) { - -				gf_log (this->name,  -					(op_errno == ENOTCONN) ?  -					GF_LOG_DEBUG:GF_LOG_ERROR, -					"child(%s): path(%s): %s",  -					priv->xl_array[(long)cookie]->name,  -					local->loc1.path, strerror (op_errno)); -				local->op_errno = op_errno; -				local->failed = 1; -			} -		} - -		if (op_ret == 0) { -			local->op_ret = 0;  -			 -			if (check_if_dht_linkfile(buf)) { -				gf_log (this->name, GF_LOG_CRITICAL, -					"file %s may be DHT link file on %s, " -					"make sure the backend is not shared " -					"between unify and DHT",  -					local->loc1.path,  -					priv->xl_array[(long)cookie]->name); -			} - -			if (local->stbuf.ia_type && local->stbuf.ia_blksize) { -				/* make sure we already have a stbuf -				   stored in local->stbuf */ -				if (IA_ISDIR (local->stbuf.ia_type) &&  -				    !IA_ISDIR (buf->ia_type)) { -					gf_log (this->name, GF_LOG_CRITICAL,  -						"[CRITICAL] '%s' is directory " -						"on namespace, non-directory " -						"on node '%s', returning EIO", -						local->loc1.path,  -						priv->xl_array[(long)cookie]->name); -					local->return_eio = 1; -				} -				if (!IA_ISDIR (local->stbuf.ia_type) &&  -				    IA_ISDIR (buf->ia_type)) { -					gf_log (this->name, GF_LOG_CRITICAL,  -						"[CRITICAL] '%s' is directory " -						"on node '%s', non-directory " -						"on namespace, returning EIO", -						local->loc1.path,  -						priv->xl_array[(long)cookie]->name); -					local->return_eio = 1; -				} -			} -	 -			if (!local->revalidate && !IA_ISDIR (buf->ia_type)) { -				/* This is the first time lookup on file*/ -				if (!local->list) { -					/* list is not allocated, allocate  -					   the max possible range */ -					local->list = GF_CALLOC (1, 2 * (priv->child_count + 2), -                                                                 gf_unify_mt_int16_t); -					if (!local->list) { -						gf_log (this->name,  -							GF_LOG_CRITICAL,  -							"Not enough memory"); -						STACK_UNWIND (frame, -1,  -							      ENOMEM, inode,  -							      NULL, NULL, NULL); -						return 0; -					} -				} -				/* update the index of the list */ -				local->list [local->index++] =  -					(int16_t)(long)cookie; -			} -                         -                        if (!local->revalidate && IA_ISDIR (buf->ia_type)) { -                                /* fresh lookup of a directory */ -                                inode_ctx_put (local->loc1.inode, this,  -                                               priv->inode_generation); -                        } - -			if ((!local->dict) && dict && -			    (priv->xl_array[(long)cookie] != NS(this)))	{ -				local->dict = dict_ref (dict); -			} - -			/* index of NS node is == total child count */ -			if (priv->child_count == (int16_t)(long)cookie) { -				/* Take the inode number from namespace */ -				local->ia_ino = buf->ia_ino; -				if (IA_ISDIR (buf->ia_type) ||  -				    !(local->stbuf.ia_blksize)) { -					local->stbuf = *buf; -                                        local->oldpostparent = *postparent; -				} -			} else if (!IA_ISDIR (buf->ia_type)) { -				/* If file, then get the stat from  -				   storage node */ -				local->stbuf = *buf; -			} - -			if (local->ia_nlink < buf->ia_nlink) { -				local->ia_nlink = buf->ia_nlink; -			} -		} -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		local_dict = local->dict; -		if (local->return_eio) { -			gf_log (this->name, GF_LOG_CRITICAL,  -				"[CRITICAL] Unable to fix the path (%s) with " -				"self-heal, try manual verification. " -				"returning EIO.", local->loc1.path); -			unify_local_wipe (local); -			STACK_UNWIND (frame, -1, EIO, inode, NULL, NULL); -			if (local_dict)	{ -				dict_unref (local_dict); -			} -			return 0; -		} - -		if (!local->stbuf.ia_blksize) { -			/* Inode not present */ -			local->op_ret = -1; -		} else { -			if (!local->revalidate &&  -			    !IA_ISDIR (local->stbuf.ia_type)) {  -				/* If its a file, big array is useless,  -				   allocate the smaller one */ -				int16_t *list = NULL; -				list = GF_CALLOC (1, 2 * (local->index + 1), -                                                  gf_unify_mt_int16_t); -				ERR_ABORT (list); -				memcpy (list, local->list, 2 * local->index); -				/* Make the end of the list as -1 */ -				GF_FREE (local->list); -				local->list = list; -				local->list [local->index] = -1; -				/* Update the inode's ctx with proper array */ -				/* TODO: log on failure */ -				inode_ctx_put (local->loc1.inode, this,  -					       (uint64_t)(long)local->list); -			} - -			if (IA_ISDIR(local->loc1.inode->ia_type)) { -				/* lookup is done for directory */ -				if (local->failed && priv->self_heal) { -					/* Triggering self-heal */ -                                        /* means, self-heal required for this  -					   inode */ -					local->inode_generation = 0;  -					priv->inode_generation++; -				} -			} else { -				local->stbuf.ia_ino = local->ia_ino; -			} -	   -			local->stbuf.ia_nlink = local->ia_nlink; -		} -		if (local->op_ret == -1) { -			if (!local->revalidate && local->list) -				GF_FREE (local->list); -		} - -		if ((local->op_ret >= 0) && local->failed &&  -		    local->revalidate) { -			/* Done revalidate, but it failed */ -			if ((op_errno != ENOTCONN)  -                            && (local->op_errno != ESTALE)) { -				gf_log (this->name, GF_LOG_ERROR,  -					"Revalidate failed for path(%s): %s",  -					local->loc1.path, strerror (op_errno)); -			} -			local->op_ret = -1; -		} - -		if ((priv->self_heal && !priv->optimist) &&  -		    (!local->revalidate && (local->op_ret == 0) &&  -		     IA_ISDIR(local->stbuf.ia_type))) { -			/* Let the self heal be done here */ -			zr_unify_self_heal (frame, this, local); -			local_dict = NULL; -		} else { -                        if (local->failed) { -                                /* NOTE: directory lookup is sent to all  -                                 * subvolumes and success from a subvolume -                                 * might set local->op_ret to 0 (zero) */ -                                local->op_ret = -1; -                        } - -			/* either no self heal, or op_ret == -1 (failure) */ -			tmp_inode = local->loc1.inode; -			unify_local_wipe (local); -			STACK_UNWIND (frame, local->op_ret, local->op_errno,  -				      tmp_inode, &local->stbuf, local->dict, -                                      &local->oldpostparent); -		} -		if (local_dict) { -			dict_unref (local_dict); -		} -	} -   -	return 0; -} - -/** - * unify_lookup -  - */ -int32_t  -unify_lookup (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *loc, -	      dict_t *xattr_req) -{ -	unify_local_t *local = NULL; -	unify_private_t *priv = this->private; -	int16_t *list = NULL; -	long index = 0; - -	if (!(loc && loc->inode)) { -		gf_log (this->name, GF_LOG_ERROR,  -			"%s: Argument not right", loc?loc->path:"(null)"); -		STACK_UNWIND (frame, -1, EINVAL, NULL, NULL, NULL, NULL); -		return 0; -	} - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, loc); -	if (local->loc1.path == NULL) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, loc->inode, NULL, NULL, NULL); -		return 0; -	} -         -        if (inode_ctx_get (loc->inode, this, NULL) -            && IA_ISDIR (loc->inode->ia_type)) { -                local->revalidate = 1; -        } - -	if (!inode_ctx_get (loc->inode, this, NULL) &&  -	    loc->inode->ia_type &&  -	    !IA_ISDIR (loc->inode->ia_type)) { -		uint64_t tmp_list = 0; -		/* check if revalidate or fresh lookup */ -		inode_ctx_get (loc->inode, this, &tmp_list); -		local->list = (int16_t *)(long)tmp_list; -	} - -	if (local->list) { -		list = local->list; -		for (index = 0; list[index] != -1; index++); -		if (index != 2) { -			if (index < 2) { -				gf_log (this->name, GF_LOG_ERROR, -					"returning ESTALE for %s: file " -					"count is %ld", loc->path, index); -				/* Print where all the file is present */ -				for (index = 0;  -				     local->list[index] != -1; index++) { -					gf_log (this->name, GF_LOG_ERROR,  -						"%s: found on %s", loc->path,  -						priv->xl_array[list[index]]->name); -				} -				unify_local_wipe (local); -				STACK_UNWIND (frame, -1, ESTALE,  -					      NULL, NULL, NULL, NULL); -				return 0;   -			} else { -				/* There are more than 2 presences */ -				/* Just log and continue */ -				gf_log (this->name, GF_LOG_ERROR, -					"%s: file count is %ld",  -					loc->path, index); -				/* Print where all the file is present */ -				for (index = 0;  -				     local->list[index] != -1; index++) { -					gf_log (this->name, GF_LOG_ERROR,  -						"%s: found on %s", loc->path,  -						priv->xl_array[list[index]]->name); -				} -			} -		} -       -		/* is revalidate */ -		local->revalidate = 1; -       -		for (index = 0; list[index] != -1; index++) -			local->call_count++; -       -		for (index = 0; list[index] != -1; index++) { -			char need_break = (list[index+1] == -1); -			STACK_WIND_COOKIE (frame, -					   unify_lookup_cbk, -					   (void *)(long)list[index], //cookie -					   priv->xl_array [list[index]], -					   priv->xl_array [list[index]]->fops->lookup, -					   loc, -					   xattr_req); -			if (need_break) -				break; -		} -	} else { -		if (loc->inode->ia_type) { -			if (inode_ctx_get (loc->inode, this, NULL)) { -				inode_ctx_get (loc->inode, this,  -					       &local->inode_generation); -			} -		} -		/* This is first call, there is no list */ -		/* call count should be all child + 1 namespace */ -		local->call_count = priv->child_count + 1; -       -		for (index = 0; index <= priv->child_count; index++) { -			STACK_WIND_COOKIE (frame, -					   unify_lookup_cbk, -					   (void *)index, //cookie -					   priv->xl_array[index], -					   priv->xl_array[index]->fops->lookup, -					   loc, -					   xattr_req); -		} -	} - -	return 0; -} - -/** - * unify_stat - if directory, get the stat directly from NameSpace child. - *     if file, check for a hint and send it only there (also to NS). - *     if its a fresh stat, then do it on all the nodes. - * - * NOTE: for all the call, sending cookie as xlator pointer, which will be  - *       used in cbk. - */ -int32_t -unify_stat (call_frame_t *frame, -	    xlator_t *this, -	    loc_t *loc) -{ -	unify_local_t *local = NULL; -	unify_private_t *priv = this->private; -	int16_t index = 0; -	int16_t *list = NULL; -	uint64_t tmp_list = 0; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, loc); -	if (local->loc1.path == NULL) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, NULL); -		return 0; -	} -	local->ia_ino = loc->inode->ino; -	if (IA_ISDIR (loc->inode->ia_type)) { -		/* Directory */ -		local->call_count = 1; -		STACK_WIND (frame, unify_buf_cbk, NS(this), -			    NS(this)->fops->stat, loc); -	} else { -		/* File */ -		inode_ctx_get (loc->inode, this, &tmp_list); -    		list = (int16_t *)(long)tmp_list; - -		for (index = 0; list[index] != -1; index++) -			local->call_count++; -     -		for (index = 0; list[index] != -1; index++) { -			char need_break = (list[index+1] == -1); -			STACK_WIND (frame, -				    unify_buf_cbk, -				    priv->xl_array[list[index]], -				    priv->xl_array[list[index]]->fops->stat, -				    loc); -			if (need_break) -				break; -		} -	} - -	return 0; -} - -/** - * unify_access_cbk - - */ -int32_t -unify_access_cbk (call_frame_t *frame, -		  void *cookie, -		  xlator_t *this, -		  int32_t op_ret, -		  int32_t op_errno) -{ -	STACK_UNWIND (frame, op_ret, op_errno); -	return 0; -} - - -/** - * unify_access - Send request to only namespace, which has all the  - *      attributes set for the file. - */ -int32_t -unify_access (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *loc, -	      int32_t mask) -{ -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	STACK_WIND (frame, -		    unify_access_cbk, -		    NS(this), -		    NS(this)->fops->access, -		    loc, -		    mask); - -	return 0; -} - -int32_t -unify_mkdir_cbk (call_frame_t *frame, -		 void *cookie, -		 xlator_t *this, -		 int32_t op_ret, -		 int32_t op_errno, -		 inode_t *inode, -                 struct iatt *buf, -                 struct iatt *preparent, -                 struct iatt *postparent) -{ -	int32_t callcnt = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	inode_t *tmp_inode = NULL; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -   -		if ((op_ret == -1) && !(priv->optimist &&  -					(op_errno == ENOENT ||  -					 op_errno == EEXIST))) { -			/* TODO: Decrement the inode_generation of  -			 * this->inode's parent inode, hence the missing  -			 * directory is created properly by self-heal.  -			 * Currently, there is no way to get the parent  -			 * inode directly. -			 */ -			gf_log (this->name, GF_LOG_ERROR, -				"child(%s): path(%s): %s",  -				priv->xl_array[(long)cookie]->name,  -				local->loc1.path, strerror (op_errno)); -			if (op_errno != EEXIST) -				local->failed = 1; -			local->op_errno = op_errno; -		} -   -		if (op_ret >= 0) -			local->op_ret = 0; - -	} -	UNLOCK (&frame->lock); -   -	if (!callcnt) { -		if (!local->failed) { -			inode_ctx_put (local->loc1.inode, this,  -				       priv->inode_generation); -		} -		 -		tmp_inode = local->loc1.inode; -		unify_local_wipe (local); - -		STACK_UNWIND (frame, local->op_ret, local->op_errno,  -			      tmp_inode, &local->stbuf, -                              &local->oldpreparent, &local->oldpostparent); -	} - -	return 0; -} - -/** - * unify_ns_mkdir_cbk - - */ -int32_t -unify_ns_mkdir_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -		    inode_t *inode, -                    struct iatt *buf, -                    struct iatt *preparent, -                    struct iatt *postparent) -{ -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	long index = 0; - -	if (op_ret == -1) { -		/* No need to send mkdir request to other servers,  -		 * as namespace action failed  -		 */ -		gf_log (this->name, GF_LOG_ERROR, -			"namespace: path(%s): %s",  -			local->name, strerror (op_errno)); -		unify_local_wipe (local); -		STACK_UNWIND (frame, op_ret, op_errno, inode, NULL, -                              NULL, NULL); -		return 0; -	} -   -	/* Create one inode for this entry */ -	local->op_ret = 0; -	local->stbuf = *buf; - -        local->oldpreparent = *preparent; -        local->oldpostparent = *postparent; - -	local->call_count = priv->child_count; - -	/* Send mkdir request to all the nodes now */ -	for (index = 0; index < priv->child_count; index++) { -		STACK_WIND_COOKIE (frame, -				   unify_mkdir_cbk, -				   (void *)index, //cookie -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->mkdir, -				   &local->loc1, -				   local->mode); -	} -   -	return 0; -} - - -/** - * unify_mkdir - - */ -int32_t -unify_mkdir (call_frame_t *frame, -	     xlator_t *this, -	     loc_t *loc, -	     mode_t mode) -{ -	unify_local_t *local = NULL; - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	local->mode = mode; - -	loc_copy (&local->loc1, loc); - -	if (local->loc1.path == NULL) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL); -		return 0; -	} - -	STACK_WIND (frame, -		    unify_ns_mkdir_cbk, -		    NS(this), -		    NS(this)->fops->mkdir, -		    loc, -		    mode); -	return 0; -} - -/** - * unify_rmdir_cbk - - */ -int32_t -unify_rmdir_cbk (call_frame_t *frame, -		 void *cookie, -		 xlator_t *this, -		 int32_t op_ret, -		 int32_t op_errno, -                 struct iatt *preparent, -                 struct iatt *postparent) -{ -	int32_t callcnt = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -		if (op_ret == 0 || (priv->optimist && (op_errno == ENOENT))) -			local->op_ret = 0; -		if (op_ret == -1) -			local->op_errno = op_errno; -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno, -                              &local->oldpreparent, &local->oldpostparent); -	} - -	return 0; -} - -/** - * unify_ns_rmdir_cbk - - */ -int32_t -unify_ns_rmdir_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -                    struct iatt *preparent, -                    struct iatt *postparent) -{ -	int16_t index = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -   -	if (op_ret == -1) { -		/* No need to send rmdir request to other servers,  -		 * as namespace action failed  -		 */ -		gf_log (this->name,  -			((op_errno != ENOTEMPTY) ?  -			 GF_LOG_ERROR : GF_LOG_DEBUG), -			"namespace: path(%s): %s",  -			local->loc1.path, strerror (op_errno)); -		unify_local_wipe (local); -		STACK_UNWIND (frame, op_ret, op_errno, NULL, NULL); -		return 0; -	} - -	local->call_count = priv->child_count; - -        local->oldpreparent = *preparent; -        local->oldpostparent = *postparent; - -	for (index = 0; index < priv->child_count; index++) { -		STACK_WIND (frame, -			    unify_rmdir_cbk, -			    priv->xl_array[index], -			    priv->xl_array[index]->fops->rmdir, -			    &local->loc1); -	} - -	return 0; -} - -/** - * unify_rmdir - - */ -int32_t -unify_rmdir (call_frame_t *frame, -	     xlator_t *this, -	     loc_t *loc) -{ -	unify_local_t *local = NULL; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	/* Initialization */ -	INIT_LOCAL (frame, local); - -	loc_copy (&local->loc1, loc); -	if (local->loc1.path == NULL) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL); -		return 0; -	} - -	STACK_WIND (frame, -		    unify_ns_rmdir_cbk, -		    NS(this), -		    NS(this)->fops->rmdir, -		    loc); - -	return 0; -} - -/** - * unify_open_cbk - - */ -int32_t -unify_open_cbk (call_frame_t *frame, -		void *cookie, -		xlator_t *this, -		int32_t op_ret, -		int32_t op_errno, -		fd_t *fd) -{ -	int32_t callcnt = 0; -	unify_local_t *local = frame->local; - -	LOCK (&frame->lock); -	{ -		if (op_ret >= 0) { -			local->op_ret = op_ret; -			if (NS(this) != (xlator_t *)cookie) { -				/* Store child node's ptr, used in  -				   all the f*** / FileIO calls */ -				fd_ctx_set (fd, this, (uint64_t)(long)cookie); -			} -		} -		if (op_ret == -1) { -			local->op_errno = op_errno; -			local->failed = 1; -		} -		callcnt = --local->call_count; -	} -	UNLOCK (&frame->lock); -   -	if (!callcnt) { -		if ((local->failed == 1) && (local->op_ret >= 0)) { -			local->call_count = 1; -			/* return -1 to user */ -			local->op_ret = -1; -			//local->op_errno = EIO;  -       -			if (!fd_ctx_get (local->fd, this, NULL)) { -				gf_log (this->name, GF_LOG_ERROR,  -					"Open success on child node, " -					"failed on namespace"); -			} else { -				gf_log (this->name, GF_LOG_ERROR,  -					"Open success on namespace, " -					"failed on child node"); -			} -		} - -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret,  -			      local->op_errno, local->fd); -	} - -	return 0; -} - -#ifdef GF_DARWIN_HOST_OS -/** - * unify_create_lookup_cbk -  - */ -int32_t  -unify_open_lookup_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno, -		       inode_t *inode, -		       struct iatt *buf, -		       dict_t *dict, -		       struct iatt *postparent) -{ -	int32_t callcnt = 0; -	int16_t index = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -		if ((op_ret == -1) && (op_errno != ENOENT)) { -			gf_log (this->name, GF_LOG_ERROR, -				"child(%s): path(%s): %s",  -				priv->xl_array[(long)cookie]->name,  -				local->loc1.path, strerror (op_errno)); -			local->op_errno = op_errno; -		} -     -		if (op_ret >= 0) { -			local->op_ret = op_ret;  -			local->index++; -			if (NS(this) == priv->xl_array[(long)cookie]) { -				local->list[0] = (int16_t)(long)cookie; -			} else { -				local->list[1] = (int16_t)(long)cookie; -			} -			if (IA_ISDIR (buf->ia_type)) -				local->failed = 1; -		} -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		int16_t file_list[3] = {0,}; -		local->op_ret = -1; - -		file_list[0] = local->list[0]; -		file_list[1] = local->list[1]; -		file_list[2] = -1; - -		if (local->index != 2) { -			/* Lookup failed, can't do open */ -			gf_log (this->name, GF_LOG_ERROR, -				"%s: present on %d nodes",  -				local->name, local->index); - -			if (local->index < 2) { -				unify_local_wipe (local); -				gf_log (this->name, GF_LOG_ERROR, -					"returning as file found on less " -					"than 2 nodes"); -				STACK_UNWIND (frame, local->op_ret,  -					      local->op_errno, local->fd); -				return 0; -			} -		} - -		if (local->failed) { -			/* Open on directory, return EISDIR */ -			unify_local_wipe (local); -			STACK_UNWIND (frame, -1, EISDIR, local->fd); -			return 0; -		} - -		/* Everything is perfect :) */     -		local->call_count = 2; -     -		for (index = 0; file_list[index] != -1; index++) { -			char need_break = (file_list[index+1] == -1); -			STACK_WIND_COOKIE (frame, -					   unify_open_cbk, -					   priv->xl_array[file_list[index]], -					   priv->xl_array[file_list[index]], -					   priv->xl_array[file_list[index]]->fops->open, -					   &local->loc1, -					   local->flags, -					   local->fd, local->wbflags); -			if (need_break) -				break; -		} -	} - -	return 0; -} - - -int32_t -unify_open_readlink_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 const char *path, -			 struct iatt *sbuf) -{ -	int16_t index = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; - -	if (op_ret == -1) { -		STACK_UNWIND (frame, -1, ENOENT); -		return 0; -	} - -	if (path[0] == '/') { -		local->name = gf_strdup (path); -		ERR_ABORT (local->name); -	} else { -		char *tmp_str = gf_strdup (local->loc1.path); -		char *tmp_base = dirname (tmp_str); -		local->name = GF_CALLOC (1, PATH_MAX, gf_unify_mt_char); -		strcpy (local->name, tmp_base); -		strncat (local->name, "/", 1); -		strcat (local->name, path); -		GF_FREE (tmp_str); -	} -   -	local->list = GF_CALLOC (1, sizeof (int16_t) * 3, -                                 gf_unify_mt_int16_t); -	ERR_ABORT (local->list); -	local->call_count = priv->child_count + 1; -	local->op_ret = -1; -	for (index = 0; index <= priv->child_count; index++) { -		/* Send the lookup to all the nodes including namespace */ -		STACK_WIND_COOKIE (frame, -				   unify_open_lookup_cbk, -				   (void *)(long)index, -				   priv->xl_array[index], -				   priv->xl_array[index]->fops->lookup, -				   &local->loc1, -				   NULL); -	} - -	return 0; -} -#endif /* GF_DARWIN_HOST_OS */ - -/** - * unify_open -  - */ -int32_t -unify_open (call_frame_t *frame, -	    xlator_t *this, -	    loc_t *loc, -	    int32_t flags, -	    fd_t *fd, -            int32_t wbflags) -{ -	unify_private_t *priv = this->private; -	unify_local_t *local = NULL; -	int16_t *list = NULL; -	int16_t index = 0; -	int16_t file_list[3] = {0,}; -	uint64_t tmp_list = 0; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	/* Init */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, loc); -	local->fd    = fd; -	local->flags = flags; -        local->wbflags = wbflags; -	inode_ctx_get (loc->inode, this, &tmp_list); -	list = (int16_t *)(long)tmp_list; - -	local->list = list; -	file_list[0] = priv->child_count; /* Thats namespace */ -	file_list[2] = -1; -	for (index = 0; list[index] != -1; index++) { -		local->call_count++; -		if (list[index] != priv->child_count) -			file_list[1] = list[index]; -	} - -	if (local->call_count != 2) { -		/* If the lookup was done for file */ -		gf_log (this->name, GF_LOG_ERROR, -			"%s: entry_count is %d", -			loc->path, local->call_count); -		for (index = 0; local->list[index] != -1; index++) -			gf_log (this->name, GF_LOG_ERROR, "%s: found on %s", -				loc->path, priv->xl_array[list[index]]->name); - -		if (local->call_count < 2) { -			gf_log (this->name, GF_LOG_ERROR, -				"returning EIO as file found on onlyone node"); -			STACK_UNWIND (frame, -1, EIO, fd); -			return 0; -		} -	} - -#ifdef GF_DARWIN_HOST_OS -	/* Handle symlink here */ -	if (IA_ISLNK (loc->inode->ia_type)) { -		/* Callcount doesn't matter here */ -		STACK_WIND (frame, -			    unify_open_readlink_cbk, -			    NS(this), -			    NS(this)->fops->readlink, -			    loc, PATH_MAX); -		return 0; -	} -#endif /* GF_DARWIN_HOST_OS */ - -	local->call_count = 2; -	for (index = 0; file_list[index] != -1; index++) { -		char need_break = (file_list[index+1] == -1); -		STACK_WIND_COOKIE (frame, -				   unify_open_cbk, -				   priv->xl_array[file_list[index]], //cookie -				   priv->xl_array[file_list[index]], -				   priv->xl_array[file_list[index]]->fops->open, -				   loc, -				   flags, -				   fd, wbflags); -		if (need_break) -			break; -	} - -	return 0; -} - - -int32_t  -unify_create_unlink_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -                         struct iatt *preparent, -                         struct iatt *postparent) -{ -	unify_local_t *local = frame->local; -	inode_t *inode = local->loc1.inode; - -	unify_local_wipe (local); - -	STACK_UNWIND (frame, local->op_ret, local->op_errno, local->fd,  -		      inode, &local->stbuf, -                      &local->oldpreparent, &local->oldpostparent); -   -	return 0; -} - -/** - * unify_create_open_cbk - - */ -int32_t -unify_create_open_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno, -		       fd_t *fd) -{ -	int ret = 0; -	int32_t callcnt = 0; -	unify_local_t *local = frame->local; -	inode_t *inode = NULL; -	xlator_t *child = NULL; -	uint64_t tmp_value = 0; - -	LOCK (&frame->lock); -	{ -		if (op_ret >= 0) { -			local->op_ret = op_ret; -			if (NS(this) != (xlator_t *)cookie) { -				/* Store child node's ptr, used in all  -				   the f*** / FileIO calls */ -				/* TODO: log on failure */ -				ret = fd_ctx_get (fd, this, &tmp_value); -				cookie = (void *)(long)tmp_value; -			} else { -				/* NOTE: open successful on namespace. -				 *       fd's ctx can be used to identify open  -				 *       failure on storage subvolume. cool  -				 *       ide ;) */ -				local->failed = 0; -			} -		} else { -			gf_log (this->name, GF_LOG_ERROR, -				"child(%s): path(%s): %s",  -				((xlator_t *)cookie)->name, -				local->loc1.path, strerror (op_errno)); -			local->op_errno = op_errno; -			local->failed = 1; -		} -		callcnt = --local->call_count; -	} -	UNLOCK (&frame->lock); -   -	if (!callcnt) { -		if (local->failed == 1 && (local->op_ret >= 0)) { -			local->call_count = 1; -			/* return -1 to user */ -			local->op_ret = -1; -			local->op_errno = EIO; -			local->fd = fd; -			local->call_count = 1; - -			if (!fd_ctx_get (local->fd, this, &tmp_value)) { -				child = (xlator_t *)(long)tmp_value; - -				gf_log (this->name, GF_LOG_ERROR,  -					"Create success on child node, " -					"failed on namespace"); - -				STACK_WIND (frame, -					    unify_create_unlink_cbk, -					    child, -					    child->fops->unlink, -					    &local->loc1); -			} else { -				gf_log (this->name, GF_LOG_ERROR,  -					"Create success on namespace, " -					"failed on child node"); - -				STACK_WIND (frame, -					    unify_create_unlink_cbk, -					    NS(this), -					    NS(this)->fops->unlink, -					    &local->loc1); -			} -			return 0; -		} -		inode = local->loc1.inode; -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno, fd, -			      inode, &local->stbuf, -                              &local->oldpreparent, &local->oldpostparent); -	} -	return 0; -} - -/** - * unify_create_lookup_cbk -  - */ -int32_t  -unify_create_lookup_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 inode_t *inode, -			 struct iatt *buf, -			 dict_t *dict, -                         struct iatt *postparent) -{ -	int32_t callcnt = 0; -	int16_t index = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -		if (op_ret == -1) { -			gf_log (this->name, GF_LOG_ERROR, -				"child(%s): path(%s): %s",  -				priv->xl_array[(long)cookie]->name,  -				local->loc1.path, strerror (op_errno)); -			local->op_errno = op_errno; -			local->failed = 1; -		} - -		if (op_ret >= 0) { -			local->op_ret = op_ret;  -			local->list[local->index++] = (int16_t)(long)cookie; -			if (NS(this) == priv->xl_array[(long)cookie]) { -				local->ia_ino = buf->ia_ino; -			} else { -				local->stbuf = *buf; -			} -		} -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		int16_t *list = local->list; -		int16_t file_list[3] = {0,}; -		local->op_ret = -1; - -		local->list [local->index] = -1; -		file_list[0] = list[0]; -		file_list[1] = list[1]; -		file_list[2] = -1; - -		local->stbuf.ia_ino = local->ia_ino; -		/* TODO: log on failure */ -		inode_ctx_put (local->loc1.inode, this,  -			       (uint64_t)(long)local->list); - -		if (local->index != 2) { -			/* Lookup failed, can't do open */ -			gf_log (this->name, GF_LOG_ERROR, -				"%s: present on %d nodes",  -				local->loc1.path, local->index); -			file_list[0] = priv->child_count; -			for (index = 0; list[index] != -1; index++) { -				gf_log (this->name, GF_LOG_ERROR,  -					"%s: found on %s", local->loc1.path,  -					priv->xl_array[list[index]]->name); -				if (list[index] != priv->child_count) -					file_list[1] = list[index]; -			} - -			if (local->index < 2) { -				unify_local_wipe (local); -				gf_log (this->name, GF_LOG_ERROR, -					"returning EIO as file found on " -					"only one node"); -				STACK_UNWIND (frame, -1, EIO,  -					      local->fd, inode, NULL, -                                              NULL, NULL); -				return 0; -			} -		} -		/* Everything is perfect :) */     -		local->call_count = 2; -     -		for (index = 0; file_list[index] != -1; index++) { -			char need_break = (file_list[index+1] == -1); -			STACK_WIND_COOKIE (frame, -					   unify_create_open_cbk, -					   priv->xl_array[file_list[index]], -					   priv->xl_array[file_list[index]], -					   priv->xl_array[file_list[index]]->fops->open, -					   &local->loc1, -					   local->flags, -					   local->fd, 0); -			if (need_break) -				break; -		} -	} - -	return 0; -} - - -/** - * unify_create_cbk - - */ -int32_t -unify_create_cbk (call_frame_t *frame, -		  void *cookie, -		  xlator_t *this, -		  int32_t op_ret, -		  int32_t op_errno, -		  fd_t *fd, -		  inode_t *inode, -		  struct iatt *buf, -                  struct iatt *preparent, -                  struct iatt *postparent) -{ -	int ret = 0; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; -	inode_t *tmp_inode = NULL; - -	if (op_ret == -1) { -		/* send unlink () on Namespace */ -		local->op_errno = op_errno; -		local->op_ret = -1; -		local->call_count = 1; -		gf_log (this->name, GF_LOG_ERROR, -			"create failed on %s (file %s, error %s), " -			"sending unlink to namespace",  -			prev_frame->this->name,  -			local->loc1.path, strerror (op_errno)); - -		STACK_WIND (frame, -			    unify_create_unlink_cbk, -			    NS(this), -			    NS(this)->fops->unlink, -			    &local->loc1); - -		return 0; -	} - -	if (op_ret >= 0) { -		local->op_ret = op_ret; -		local->stbuf = *buf; -		/* Just inode number should be from NS node */ -		local->stbuf.ia_ino = local->ia_ino; - -		/* TODO: log on failure */ -		ret = fd_ctx_set (fd, this, (uint64_t)(long)prev_frame->this); -	} -   -	tmp_inode = local->loc1.inode; -	unify_local_wipe (local); -	STACK_UNWIND (frame, local->op_ret, local->op_errno, local->fd,  -		      tmp_inode, &local->stbuf, -                      &local->oldpreparent, &local->oldpostparent); - -	return 0; -} - -/** - * unify_ns_create_cbk - - *  - */ -int32_t -unify_ns_create_cbk (call_frame_t *frame, -		     void *cookie, -		     xlator_t *this, -		     int32_t op_ret, -		     int32_t op_errno, -		     fd_t *fd, -		     inode_t *inode, -		     struct iatt *buf, -                     struct iatt *preparent, -                     struct iatt *postparent) -{ -	struct sched_ops *sched_ops = NULL; -	xlator_t *sched_xl = NULL; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	int16_t *list = NULL; -	int16_t index = 0; - -	if (op_ret == -1) { -		/* No need to send create request to other servers, as  -		   namespace action failed. Handle exclusive create here. */ -		if ((op_errno != EEXIST) ||  -		    ((op_errno == EEXIST) &&  -		     ((local->flags & O_EXCL) == O_EXCL))) { -			/* If its just a create call without O_EXCL,  -			   don't do this */ -			gf_log (this->name, GF_LOG_ERROR, -				"namespace: path(%s): %s",  -				local->loc1.path, strerror (op_errno)); -			unify_local_wipe (local); -			STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf, -                                      preparent, postparent); -			return 0; -		} -	} -   -	if (op_ret >= 0) { -		/* Get the inode number from the NS node */ -		local->ia_ino = buf->ia_ino; -   -                local->oldpreparent = *preparent; -                local->oldpostparent = *postparent; - -		local->op_ret = -1; - -		/* Start the mapping list */ -		list = GF_CALLOC (1, sizeof (int16_t) * 3, -                                  gf_unify_mt_int16_t); -		ERR_ABORT (list); -		inode_ctx_put (inode, this, (uint64_t)(long)list); -		list[0] = priv->child_count; -		list[2] = -1; - -		/* This means, file doesn't exist anywhere in the Filesystem */ -		sched_ops = priv->sched_ops; - -		/* Send create request to the scheduled node now */ -		sched_xl = sched_ops->schedule (this, local->loc1.path); -		if (sched_xl == NULL) -		{ -			/* send unlink () on Namespace */ -			local->op_errno = ENOTCONN; -			local->op_ret = -1; -			local->call_count = 1; -			gf_log (this->name, GF_LOG_ERROR, -				"no node online to schedule create:(file %s) " -				"sending unlink to namespace",  -				(local->loc1.path)?local->loc1.path:""); - -			STACK_WIND (frame, -				    unify_create_unlink_cbk, -				    NS(this), -				    NS(this)->fops->unlink, -				    &local->loc1); -	 -			return 0; -		} - -		for (index = 0; index < priv->child_count; index++) -			if (sched_xl == priv->xl_array[index]) -				break; -		list[1] = index; - -		STACK_WIND (frame, unify_create_cbk, -			    sched_xl, sched_xl->fops->create, -			    &local->loc1, local->flags, local->mode, fd); -	} else { -		/* File already exists, and there is no O_EXCL flag */ - -		gf_log (this->name, GF_LOG_DEBUG,  -			"File(%s) already exists on namespace, sending " -			"open instead", local->loc1.path); - -		local->list = GF_CALLOC (1, sizeof (int16_t) * 3, -                                         gf_unify_mt_int16_t); -		ERR_ABORT (local->list); -		local->call_count = priv->child_count + 1; -		local->op_ret = -1; -		for (index = 0; index <= priv->child_count; index++) { -			/* Send lookup() to all nodes including namespace */ -			STACK_WIND_COOKIE (frame, -					   unify_create_lookup_cbk, -					   (void *)(long)index, -					   priv->xl_array[index], -					   priv->xl_array[index]->fops->lookup, -					   &local->loc1, -					   NULL); -		} -	} -	return 0; -} - -/** - * unify_create - create a file in global namespace first, so other  - *    clients can see them. Create the file in storage nodes in background. - */ -int32_t -unify_create (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *loc, -	      int32_t flags, -	      mode_t mode, -	      fd_t *fd) -{ -	unify_local_t *local = NULL; -   -	/* Initialization */ -	INIT_LOCAL (frame, local); -	local->mode = mode; -	local->flags = flags; -	local->fd = fd; - -	loc_copy (&local->loc1, loc); -	if (local->loc1.path == NULL) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, fd, loc->inode, NULL, -                              NULL, NULL); -		return 0; -	} - -	STACK_WIND (frame, -		    unify_ns_create_cbk, -		    NS(this), -		    NS(this)->fops->create, -		    loc, -		    flags | O_EXCL, -		    mode, -		    fd); -   -	return 0; -} - - -/** - * unify_opendir_cbk -  - */ -int32_t -unify_opendir_cbk (call_frame_t *frame, -		   void *cookie, -		   xlator_t *this, -		   int32_t op_ret, -		   int32_t op_errno, -		   fd_t *fd) -{ -	STACK_UNWIND (frame, op_ret, op_errno, fd); - -	return 0; -} - -/**  - * unify_opendir - - */ -int32_t -unify_opendir (call_frame_t *frame, -	       xlator_t *this, -	       loc_t *loc, -	       fd_t *fd) -{ -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	STACK_WIND (frame, unify_opendir_cbk, -		    NS(this), NS(this)->fops->opendir, loc, fd); - -	return 0; -} - - -int32_t -unify_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) -{ -	int32_t callcnt = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -     -		if (op_ret == -1) { -			gf_log (this->name, GF_LOG_ERROR, -				"%s(): child(%s): path(%s): %s",  -				gf_fop_list[frame->root->op], -				prev_frame->this->name,  -				(local->loc1.path)?local->loc1.path:"",  -				strerror (op_errno)); - -			local->op_errno = op_errno; -			if ((op_errno == ENOENT) && priv->optimist)  -				local->op_ret = 0; -		} - -		if (op_ret >= 0) { -			local->op_ret = 0; - -			if (NS (this) == prev_frame->this) { -				local->ia_ino = statpost->ia_ino; -				/* If the entry is directory, get the stat -				   from NS node */ -				if (IA_ISDIR (statpost->ia_type) ||  -				    !local->stpost.ia_blksize) { -					local->stpre = *statpre; -                                        local->stpost = *statpost; -				} -			} - -			if ((!IA_ISDIR (statpost->ia_type)) &&  -			    (NS (this) != prev_frame->this)) { -				/* If file, take the stat info from Storage  -				   node. */ -				local->stpre = *statpre; -                                local->stpost = *statpost; -			} -		} -	} -	UNLOCK (&frame->lock); -     -	if (!callcnt) { -		/* If the inode number is not filled, operation should -		   fail */ -		if (!local->ia_ino) -			local->op_ret = -1; - -                local->stpre.ia_ino = local->ia_ino; -		local->stpost.ia_ino = local->ia_ino; -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno,  -			      &local->stpre, &local->stpost); -	} - -	return 0; -} - - -int32_t -unify_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, -               struct iatt *stbuf, int32_t valid) -{ -	unify_local_t *local = NULL; -	unify_private_t *priv = this->private; -	int32_t index = 0; -	int32_t callcnt = 0; -  	uint64_t tmp_list = 0; - -        if (!(loc && loc->inode)) {                      -                STACK_UNWIND (frame, -1, EINVAL, NULL, NULL); -                return 0; -        }                                                     - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, loc); - -	if (IA_ISDIR (loc->inode->ia_type)) { -		local->call_count = 1; -       -                STACK_WIND (frame, -                            unify_setattr_cbk, -                            NS (this), -                            NS (this)->fops->setattr, -                            loc, stbuf, valid); -        } else { -		inode_ctx_get (loc->inode, this, &tmp_list); -		local->list = (int16_t *)(long)tmp_list; - -		for (index = 0; local->list[index] != -1; index++) { -			local->call_count++; -			callcnt++; -		} -       -		for (index = 0; local->list[index] != -1; index++) { -			STACK_WIND (frame, -				    unify_setattr_cbk, -				    priv->xl_array[local->list[index]], -				    priv->xl_array[local->list[index]]->fops->setattr, -				    loc, stbuf, valid); - -			if (!--callcnt) -				break; -		} -	} - -	return 0; -} - - -int32_t -unify_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, -                struct iatt *stbuf, int32_t valid) -{ -	unify_local_t *local = NULL; -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(fd); - -	/* Initialization */ -	INIT_LOCAL (frame, local); - -	if (!fd_ctx_get (fd, this, &tmp_child)) { -		/* If its set, then its file */ -		child = (xlator_t *)(long)tmp_child;		      - -		local->call_count = 2; - -		STACK_WIND (frame, unify_setattr_cbk, child, -			    child->fops->fsetattr, fd, stbuf, valid); - -		STACK_WIND (frame, unify_setattr_cbk, NS(this), -			    NS(this)->fops->fsetattr, fd, stbuf, valid); -	} else { -		local->call_count = 1; -     -		STACK_WIND (frame, unify_setattr_cbk, -			    NS(this), NS(this)->fops->fsetattr, -			    fd, stbuf, valid); -	} -   -	return 0; -} - - -/** - * unify_truncate_cbk -  - */ -int32_t -unify_truncate_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -		    struct iatt *prebuf, -                    struct iatt *postbuf) -{ -	int32_t callcnt = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -     -		if (op_ret == -1) { -			gf_log (this->name, GF_LOG_ERROR, -				"child(%s): path(%s): %s",  -				prev_frame->this->name,  -				(local->loc1.path)?local->loc1.path:"",  -				strerror (op_errno)); -			local->op_errno = op_errno; -			if (!((op_errno == ENOENT) && priv->optimist)) -				local->op_ret = -1; -		} - -		if (op_ret >= 0) { -			if (NS (this) == prev_frame->this) { -				local->ia_ino = postbuf->ia_ino; -				/* If the entry is directory, get the  -				   stat from NS node */ -				if (IA_ISDIR (postbuf->ia_type) || -				    !local->stbuf.ia_blksize) { -					local->stbuf = *prebuf; -                                        local->poststbuf = *postbuf; -				} -			} - -			if ((!IA_ISDIR (postbuf->ia_type)) && -			    (NS (this) != prev_frame->this)) { -				/* If file, take the stat info from  -				   Storage node. */ -				local->stbuf = *prebuf; -                                local->poststbuf = *postbuf; -			} -		} -	} -	UNLOCK (&frame->lock); -     -	if (!callcnt) { -		if (local->ia_ino) { -			local->stbuf.ia_ino = local->ia_ino; -                        local->poststbuf.ia_ino = local->ia_ino; -                } else { -			local->op_ret = -1; -                } -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno,  -			      &local->stbuf, &local->poststbuf); -	} - -	return 0; -} - - -/** - * unify_truncate -  - */ -int32_t -unify_truncate (call_frame_t *frame, -		xlator_t *this, -		loc_t *loc, -		off_t offset) -{ -	unify_local_t *local = NULL; -	unify_private_t *priv = this->private; -	int32_t index = 0; -	int32_t callcnt = 0; -  	uint64_t tmp_list = 0; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, loc); -	local->ia_ino = loc->inode->ino; - -	if (IA_ISDIR (loc->inode->ia_type)) { -		local->call_count = 1; -       -		STACK_WIND (frame, -			    unify_truncate_cbk, -			    NS(this), -			    NS(this)->fops->truncate, -			    loc, -                            0); -	} else { -		local->op_ret = 0; -		inode_ctx_get (loc->inode, this, &tmp_list); -		local->list = (int16_t *)(long)tmp_list; - -		for (index = 0; local->list[index] != -1; index++) { -			local->call_count++; -			callcnt++; -		} -       -		/* Don't send offset to NS truncate */ -		STACK_WIND (frame, unify_truncate_cbk, NS(this), -			    NS(this)->fops->truncate, loc, 0); -		callcnt--; - -		for (index = 0; local->list[index] != -1; index++) { -			if (NS(this) != priv->xl_array[local->list[index]]) { -				STACK_WIND (frame, -					    unify_truncate_cbk, -					    priv->xl_array[local->list[index]], -					    priv->xl_array[local->list[index]]->fops->truncate, -					    loc, -					    offset); -				if (!--callcnt) -					break; -			} -		} -	} - -	return 0; -} - -/** - * unify_readlink_cbk -  - */ -int32_t -unify_readlink_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -		    const char *path, -                    struct iatt *sbuf) -{ -	STACK_UNWIND (frame, op_ret, op_errno, path, sbuf); -	return 0; -} - -/** - * unify_readlink - Read the link only from the storage node. - */ -int32_t -unify_readlink (call_frame_t *frame, -		xlator_t *this, -		loc_t *loc, -		size_t size) -{ -	unify_private_t *priv = this->private; -	int32_t entry_count = 0; -	int16_t *list = NULL; -	int16_t index = 0; -  	uint64_t tmp_list = 0; -   -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); -	 -	inode_ctx_get (loc->inode, this, &tmp_list); -	list = (int16_t *)(long)tmp_list; - -	for (index = 0; list[index] != -1; index++) -		entry_count++; - -	if (entry_count >= 2) { -		for (index = 0; list[index] != -1; index++) { -			if (priv->xl_array[list[index]] != NS(this)) { -				STACK_WIND (frame, -					    unify_readlink_cbk, -					    priv->xl_array[list[index]], -					    priv->xl_array[list[index]]->fops->readlink, -					    loc, -					    size); -				break; -			} -		} -	} else { -		gf_log (this->name, GF_LOG_ERROR,  -			"returning ENOENT, no softlink files found " -			"on storage node"); -		STACK_UNWIND (frame, -1, ENOENT, NULL); -	} - -	return 0; -} - - -/** - * unify_unlink_cbk -  - */ -int32_t -unify_unlink_cbk (call_frame_t *frame, -		  void *cookie, -		  xlator_t *this, -		  int32_t op_ret, -		  int32_t op_errno, -                  struct iatt *preparent, -                  struct iatt *postparent) -{ -	int32_t callcnt = 0; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -		if (op_ret == 0  || ((op_errno == ENOENT) && priv->optimist)) -			local->op_ret = 0; -		if (op_ret == -1) -			local->op_errno = op_errno; - -                if (((call_frame_t *)cookie)->this == NS(this)) { -                        local->oldpreparent = *preparent; -                        local->oldpostparent = *postparent; -                } -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno, -                              &local->oldpreparent, &local->oldpostparent); -	} - -	return 0; -} - - -/** - * unify_unlink -  - */ -int32_t -unify_unlink (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *loc) -{ -	unify_private_t *priv = this->private; -	unify_local_t *local = NULL; -	int16_t *list = NULL; -	int16_t index = 0; -  	uint64_t tmp_list = 0; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, loc); - -	inode_ctx_get (loc->inode, this, &tmp_list); -	list = (int16_t *)(long)tmp_list; - -	for (index = 0; list[index] != -1; index++) -		local->call_count++; - -	if (local->call_count) { -		for (index = 0; list[index] != -1; index++) { -			char need_break = (list[index+1] == -1); -			STACK_WIND (frame, -				    unify_unlink_cbk, -				    priv->xl_array[list[index]], -				    priv->xl_array[list[index]]->fops->unlink, -				    loc); -			if (need_break) -				break; -		} -	} else { -		gf_log (this->name, GF_LOG_ERROR, -			"%s: returning ENOENT", loc->path); -		STACK_UNWIND (frame, -1, ENOENT, NULL, NULL); -	} - -	return 0; -} - - -/** - * unify_readv_cbk -  - */ -int32_t -unify_readv_cbk (call_frame_t *frame, -		 void *cookie, -		 xlator_t *this, -		 int32_t op_ret, -		 int32_t op_errno, -		 struct iovec *vector, -		 int32_t count, -		 struct iatt *stbuf, -                 struct iobref *iobref) -{ -	STACK_UNWIND (frame, op_ret, op_errno, vector, count, stbuf, iobref); -	return 0; -} - -/** - * unify_readv -  - */ -int32_t -unify_readv (call_frame_t *frame, -	     xlator_t *this, -	     fd_t *fd, -	     size_t size, -	     off_t offset) -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, -		    unify_readv_cbk, -		    child, -		    child->fops->readv, -		    fd, -		    size, -		    offset); - - -	return 0; -} - -/** - * unify_writev_cbk -  - */ -int32_t -unify_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) -{ -	unify_local_t *local = NULL; - -        local = frame->local; - -        local->stbuf = *prebuf; -        local->stbuf.ia_ino = local->ia_ino; - -        local->poststbuf = *postbuf; -        local->poststbuf.ia_ino = local->ia_ino; - -	STACK_UNWIND (frame, op_ret, op_errno, -                      &local->stbuf, &local->poststbuf); -	return 0; -} - -/** - * unify_writev -  - */ -int32_t -unify_writev (call_frame_t *frame, -	      xlator_t *this, -	      fd_t *fd, -	      struct iovec *vector, -	      int32_t count, -	      off_t off, -              struct iobref *iobref) -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; -	unify_local_t *local = NULL; - -	INIT_LOCAL (frame, local); -        local->ia_ino = fd->inode->ino; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, -		    unify_writev_cbk, -		    child, -		    child->fops->writev, -		    fd, -		    vector, -		    count, -		    off, -                    iobref); - -	return 0; -} - -/** - * unify_ftruncate - - */ -int32_t -unify_ftruncate (call_frame_t *frame, -		 xlator_t *this, -		 fd_t *fd, -		 off_t offset) -{ -	xlator_t *child = NULL; -	unify_local_t *local = NULL; -	uint64_t tmp_child = 0; - -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR(fd); - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	local->op_ret = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	local->call_count = 2; -   -	STACK_WIND (frame, unify_truncate_cbk, -		    child, child->fops->ftruncate, -		    fd, offset); -   -	STACK_WIND (frame, unify_truncate_cbk, -		    NS(this), NS(this)->fops->ftruncate, -		    fd, 0); -   -	return 0; -} - - -/** - * unify_flush_cbk -  - */ -int32_t -unify_flush_cbk (call_frame_t *frame, -		 void *cookie, -		 xlator_t *this, -		 int32_t op_ret, -		 int32_t op_errno) -{ -	STACK_UNWIND (frame, op_ret, op_errno); -	return 0; -} - -/** - * unify_flush - - */ -int32_t -unify_flush (call_frame_t *frame, -	     xlator_t *this, -	     fd_t *fd) -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, unify_flush_cbk, child,  -		    child->fops->flush, fd); - -	return 0; -} - - -/** - * unify_fsync_cbk -  - */ -int32_t -unify_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) -{ -	STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf); -	return 0; -} - -/** - * unify_fsync -  - */ -int32_t -unify_fsync (call_frame_t *frame, -	     xlator_t *this, -	     fd_t *fd, -	     int32_t flags) -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, unify_fsync_cbk, child, -		    child->fops->fsync, fd, flags); - -	return 0; -} - -/** - * unify_fstat - Send fstat FOP to Namespace only if its directory, and to  - *     both namespace and the storage node if its a file. - */ -int32_t -unify_fstat (call_frame_t *frame, -	     xlator_t *this, -	     fd_t *fd) -{ -	unify_local_t *local = NULL; -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(fd); - -	INIT_LOCAL (frame, local); -	local->ia_ino = fd->inode->ino; - -	if (!fd_ctx_get (fd, this, &tmp_child)) { -		/* If its set, then its file */ -		child = (xlator_t *)(long)tmp_child;		      -		local->call_count = 2; - -		STACK_WIND (frame, unify_buf_cbk, child, -			    child->fops->fstat, fd); - -		STACK_WIND (frame, unify_buf_cbk, NS(this), -			    NS(this)->fops->fstat, fd); - -	} else { -		/* this is an directory */ -		local->call_count = 1; -		STACK_WIND (frame, unify_buf_cbk, NS(this), -			    NS(this)->fops->fstat, fd); -	} - -	return 0; -} - -/** - * unify_getdents_cbk -  - */ -int32_t -unify_getdents_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -		    dir_entry_t *entry, -		    int32_t count) -{ -	STACK_UNWIND (frame, op_ret, op_errno, entry, count); -	return 0; -} - -/** - * unify_getdents - send the FOP request to all the nodes. - */ -int32_t -unify_getdents (call_frame_t *frame, -		xlator_t *this, -		fd_t *fd, -		size_t size, -		off_t offset, -		int32_t flag) -{ -	UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd); - -	STACK_WIND (frame, unify_getdents_cbk, NS(this), -		    NS(this)->fops->getdents, fd, size, offset, flag); - -	return 0; -} - - -/** - * unify_readdir_cbk -  - */ -int32_t -unify_readdir_cbk (call_frame_t *frame, -		   void *cookie, -		   xlator_t *this, -		   int32_t op_ret, -		   int32_t op_errno, -		   gf_dirent_t *buf) -{ -	STACK_UNWIND (frame, op_ret, op_errno, buf); - -	return 0; -} - -/** - * unify_readdir - send the FOP request to all the nodes. - */ -int32_t -unify_readdir (call_frame_t *frame, -	       xlator_t *this, -	       fd_t *fd, -	       size_t size, -	       off_t offset) -{ -	UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd); - -	STACK_WIND (frame, unify_readdir_cbk, NS(this), -		    NS(this)->fops->readdir, fd, size, offset); - -	return 0; -} - - -int32_t -unify_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, gf_dirent_t *buf) -{ -	STACK_UNWIND (frame, op_ret, op_errno, buf); - -	return 0; -} - - -int32_t -unify_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -                off_t offset) -{ -	UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd); - -	STACK_WIND (frame, unify_readdirp_cbk, NS(this), -		    NS(this)->fops->readdirp, fd, size, offset); - -	return 0; -} - - -/** - * unify_fsyncdir_cbk -  - */ -int32_t -unify_fsyncdir_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno) -{ -	STACK_UNWIND (frame, op_ret, op_errno); - -	return 0; -} - -/** - * unify_fsyncdir - - */ -int32_t -unify_fsyncdir (call_frame_t *frame, -		xlator_t *this, -		fd_t *fd, -		int32_t flags) -{ -	UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd); - -	STACK_WIND (frame, unify_fsyncdir_cbk, -		    NS(this), NS(this)->fops->fsyncdir, fd, flags); - -	return 0; -} - -/** - * unify_lk_cbk - UNWIND frame with the proper return arguments. - */ -int32_t -unify_lk_cbk (call_frame_t *frame, -	      void *cookie, -	      xlator_t *this, -	      int32_t op_ret, -	      int32_t op_errno, -	      struct gf_flock *lock) -{ -	STACK_UNWIND (frame, op_ret, op_errno, lock); -	return 0; -} - -/** - * unify_lk - Send it to all the storage nodes, (should be 1) which has file. - */ -int32_t -unify_lk (call_frame_t *frame, -	  xlator_t *this, -	  fd_t *fd, -	  int32_t cmd, -	  struct gf_flock *lock) -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, unify_lk_cbk, child, -		    child->fops->lk, fd, cmd, lock); - -	return 0; -} - - -int32_t -unify_setxattr_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno); - -static int32_t -unify_setxattr_file_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno) -{ -	unify_private_t *private = this->private; -	unify_local_t *local = frame->local; -	xlator_t *sched_xl = NULL; -	struct sched_ops *sched_ops = NULL; - -	if (op_ret == -1) { -		if (!ENOTSUP) -			gf_log (this->name, GF_LOG_ERROR, -				"setxattr with XATTR_CREATE on ns: " -				"path(%s) key(%s): %s", -				local->loc1.path, local->name,  -				strerror (op_errno)); -		unify_local_wipe (local); -		STACK_UNWIND (frame, op_ret, op_errno); -		return 0; -	}  - -	LOCK (&frame->lock); -	{ -		local->failed = 0; -		local->op_ret = 0; -		local->op_errno = 0; -		local->call_count = 1; -	} -	UNLOCK (&frame->lock); - -	/* schedule XATTR_CREATE on one of the child node */ -	sched_ops = private->sched_ops; -     -	/* Send create request to the scheduled node now */ -	sched_xl = sched_ops->schedule (this, local->name);  -	if (!sched_xl) { -		STACK_UNWIND (frame, -1, ENOTCONN); -		return 0; -	} - -	STACK_WIND (frame, -		    unify_setxattr_cbk, -		    sched_xl, -		    sched_xl->fops->setxattr, -		    &local->loc1, -		    local->dict, -		    local->flags); -	return 0; -} - -/** - * unify_setxattr_cbk - When all the child nodes return, UNWIND frame. - */ -int32_t -unify_setxattr_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno) -{ -	int32_t callcnt = 0; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; -	dict_t *dict = NULL; - -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -     -		if (op_ret == -1) { -			gf_log (this->name, (((op_errno == ENOENT) ||  -					      (op_errno == ENOTSUP))?  -					     GF_LOG_DEBUG : GF_LOG_ERROR),  -				"child(%s): path(%s): %s",  -				prev_frame->this->name,  -				(local->loc1.path)?local->loc1.path:"",  -				strerror (op_errno)); -			if (local->failed == -1) { -				local->failed = 1; -			} -			local->op_errno = op_errno; -		} else { -			local->failed = 0; -			local->op_ret = op_ret; -		} -	} -	UNLOCK (&frame->lock); -   -	if (!callcnt) { -		if (local->failed && local->name &&  -		    ZR_FILE_CONTENT_REQUEST(local->name)) {       -			dict = get_new_dict (); -			dict_set (dict, local->dict->members_list->key,  -				  data_from_dynptr(NULL, 0)); -			dict_ref (dict); - -			local->call_count = 1; - -			STACK_WIND (frame, -				    unify_setxattr_file_cbk, -				    NS(this), -				    NS(this)->fops->setxattr, -				    &local->loc1, -				    dict, -				    XATTR_CREATE); - -			dict_unref (dict); -			return 0; -		} -     -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno); -	} - -	return 0; -} - -/** - * unify_sexattr - This function should be sent to all the storage nodes,  - *       which contains the file, (excluding namespace). - */ -int32_t -unify_setxattr (call_frame_t *frame, -		xlator_t *this, -		loc_t *loc, -		dict_t *dict, -		int32_t flags) -{ -	unify_private_t *priv = this->private; -	unify_local_t *local = NULL; -	int16_t *list = NULL; -	int16_t index = 0; -	int32_t call_count = 0; -  	uint64_t tmp_list = 0; -	data_pair_t *trav = dict->members_list; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	local->failed = -1; -	loc_copy (&local->loc1, loc); - -	if (IA_ISDIR (loc->inode->ia_type)) { - -		if (trav && trav->key && ZR_FILE_CONTENT_REQUEST(trav->key)) { -			/* direct the storage xlators to change file  -			   content only if file exists */ -			local->flags = flags; -			local->dict = dict; -			local->name = gf_strdup (trav->key); -			flags |= XATTR_REPLACE; -		} - -		local->call_count = priv->child_count; -		for (index = 0; index < priv->child_count; index++) { -			STACK_WIND (frame, -				    unify_setxattr_cbk, -				    priv->xl_array[index], -				    priv->xl_array[index]->fops->setxattr, -				    loc, dict, flags); -		} -		return 0; -	} - -	inode_ctx_get (loc->inode, this, &tmp_list); -	list = (int16_t *)(long)tmp_list; - -	for (index = 0; list[index] != -1; index++) { -		if (NS(this) != priv->xl_array[list[index]]) { -			local->call_count++; -			call_count++; -		} -	} -   -	if (local->call_count) { -		for (index = 0; list[index] != -1; index++) { -			if (priv->xl_array[list[index]] != NS(this)) { -				STACK_WIND (frame, -					    unify_setxattr_cbk, -					    priv->xl_array[list[index]], -					    priv->xl_array[list[index]]->fops->setxattr, -					    loc, -					    dict, -					    flags); -				if (!--call_count) -					break; -			} -		} -		return 0; -	} - -	/* No entry in storage nodes */ -	gf_log (this->name, GF_LOG_DEBUG,  -		"returning ENOENT, file not found on storage node."); -	STACK_UNWIND (frame, -1, ENOENT); - -	return 0; -} - - -/** - * unify_getxattr_cbk - This function is called from only one child, so, no - *     need of any lock or anything else, just send it to above layer  - */ -int32_t -unify_getxattr_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -		    dict_t *value) -{ -	int32_t callcnt = 0; -	dict_t *local_value = NULL; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; -   -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -     -		if (op_ret == -1) { -			local->op_errno = op_errno; -			gf_log (this->name,  -				(((op_errno == ENOENT) ||  -				  (op_errno == ENODATA) ||  -				  (op_errno == ENOTSUP)) ?  -				 GF_LOG_DEBUG : GF_LOG_ERROR),  -				"child(%s): path(%s): %s",  -				prev_frame->this->name,  -				(local->loc1.path)?local->loc1.path:"",  -				strerror (op_errno)); -		} else { -			if (!local->dict) -				local->dict = dict_ref (value); -			local->op_ret = op_ret; -		} -	} -	UNLOCK (&frame->lock); -   -	if (!callcnt) { -		local_value = local->dict; -		local->dict = NULL; -       -		STACK_UNWIND (frame, local->op_ret, local->op_errno,  -			      local_value); -       -		if (local_value) -			dict_unref (local_value); -	}  - -	return 0; -} - - -/**  - * unify_getxattr - This FOP is sent to only the storage node. - */ -int32_t -unify_getxattr (call_frame_t *frame, -		xlator_t *this, -		loc_t *loc, -		const char *name) -{ -	unify_private_t *priv = this->private; -	int16_t *list = NULL; -	int16_t index = 0; -	int16_t count = 0; -	unify_local_t *local = NULL; -  	uint64_t tmp_list = 0; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); -	INIT_LOCAL (frame, local); - -	if (IA_ISDIR (loc->inode->ia_type)) { -		local->call_count = priv->child_count; -		for (index = 0; index < priv->child_count; index++) -			STACK_WIND (frame, -				    unify_getxattr_cbk, -				    priv->xl_array[index], -				    priv->xl_array[index]->fops->getxattr, -				    loc, -				    name); -		return 0; -	} - -	inode_ctx_get (loc->inode, this, &tmp_list); -	list = (int16_t *)(long)tmp_list; - -	for (index = 0; list[index] != -1; index++) { -		if (NS(this) != priv->xl_array[list[index]]) { -			local->call_count++; -			count++; -		} -	} - -	if (count) { -		for (index = 0; list[index] != -1; index++) { -			if (priv->xl_array[list[index]] != NS(this)) { -				STACK_WIND (frame, -					    unify_getxattr_cbk, -					    priv->xl_array[list[index]], -					    priv->xl_array[list[index]]->fops->getxattr, -					    loc, -					    name); -				if (!--count) -					break; -			} -		} -	} else { -		dict_t *tmp_dict = get_new_dict (); -		gf_log (this->name, GF_LOG_DEBUG,  -			"%s: returning ENODATA, no file found on storage node", -			loc->path); -		STACK_UNWIND (frame, -1, ENODATA, tmp_dict); -		dict_destroy (tmp_dict); -	} - -	return 0; -} - -/** - * unify_removexattr_cbk - Wait till all the child node returns the call - *      and then UNWIND to above layer. - */ -int32_t -unify_removexattr_cbk (call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno) -{ -	int32_t callcnt = 0; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; - -	LOCK (&frame->lock); -	{  -		callcnt = --local->call_count; -		if (op_ret == -1) { -			local->op_errno = op_errno; -			if (op_errno != ENOTSUP) -				gf_log (this->name, GF_LOG_ERROR,  -					"child(%s): path(%s): %s",  -					prev_frame->this->name,  -					local->loc1.path, strerror (op_errno)); -		} else { -			local->op_ret = op_ret; -		} -	} -	UNLOCK (&frame->lock);   - -	if (!callcnt) { -		STACK_UNWIND (frame, local->op_ret, local->op_errno); -	} - -	return 0; -} - -/** - * unify_removexattr - Send it to all the child nodes which has the files. - */ -int32_t -unify_removexattr (call_frame_t *frame, -		   xlator_t *this, -		   loc_t *loc, -		   const char *name) -{ -	unify_private_t *priv = this->private; -	unify_local_t *local = NULL; -	int16_t *list = NULL; -	int16_t index = 0; -	int32_t call_count = 0; -  	uint64_t tmp_list = 0; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - -	/* Initialization */ -	INIT_LOCAL (frame, local); - -	if (IA_ISDIR (loc->inode->ia_type)) { -		local->call_count = priv->child_count; -		for (index = 0; index < priv->child_count; index++) -			STACK_WIND (frame, 		     -				    unify_removexattr_cbk, -				    priv->xl_array[index], -				    priv->xl_array[index]->fops->removexattr, -				    loc, -				    name); - -		return 0; -	} - -	inode_ctx_get (loc->inode, this, &tmp_list); -	list = (int16_t *)(long)tmp_list; - -	for (index = 0; list[index] != -1; index++) { -		if (NS(this) != priv->xl_array[list[index]]) { -			local->call_count++; -			call_count++; -		} -	} - -	if (local->call_count) { -		for (index = 0; list[index] != -1; index++) { -			if (priv->xl_array[list[index]] != NS(this)) { -				STACK_WIND (frame, -					    unify_removexattr_cbk, -					    priv->xl_array[list[index]], -					    priv->xl_array[list[index]]->fops->removexattr, -					    loc, -					    name); -				if (!--call_count) -					break; -			} -		} -		return 0; -	}  - -	gf_log (this->name, GF_LOG_DEBUG,  -		"%s: returning ENOENT, not found on storage node.", loc->path); -	STACK_UNWIND (frame, -1, ENOENT); - -	return 0; -} - - -int32_t  -unify_mknod_unlink_cbk (call_frame_t *frame, -			void *cookie, -			xlator_t *this, -			int32_t op_ret, -			int32_t op_errno, -                        struct iatt *preparent, -                        struct iatt *postparent) -{ -	unify_local_t *local = frame->local; - -	if (op_ret == -1) -		gf_log (this->name, GF_LOG_ERROR,  -			"%s: %s", local->loc1.path, strerror (op_errno)); -   -	unify_local_wipe (local); -	/* No log required here as this -1 is for mknod call */ -	STACK_UNWIND (frame, -1, local->op_errno, NULL, NULL); -	return 0; -} - -/** - * unify_mknod_cbk -  - */ -int32_t -unify_mknod_cbk (call_frame_t *frame, -		 void *cookie, -		 xlator_t *this, -		 int32_t op_ret, -		 int32_t op_errno, -		 inode_t *inode, -                 struct iatt *buf, -                 struct iatt *preparent, -                 struct iatt *postparent) -{ -	unify_local_t *local = frame->local; - -	if (op_ret == -1) { -		gf_log (this->name, GF_LOG_ERROR,  -			"mknod failed on storage node, sending unlink to " -			"namespace"); -		local->op_errno = op_errno; -		STACK_WIND (frame, -			    unify_mknod_unlink_cbk, -			    NS(this), -			    NS(this)->fops->unlink, -			    &local->loc1); -		return 0; -	} -   -	local->stbuf = *buf; -	local->stbuf.ia_ino = local->ia_ino; -	unify_local_wipe (local); -	STACK_UNWIND (frame, op_ret, op_errno, inode, &local->stbuf, -                      &local->oldpreparent, &local->oldpostparent); -	return 0; -} - -/** - * unify_ns_mknod_cbk -  - */ -int32_t -unify_ns_mknod_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -		    inode_t *inode, -                    struct iatt *buf, -                    struct iatt *preparent, -                    struct iatt *postparent) -{ -	struct sched_ops *sched_ops = NULL; -	xlator_t *sched_xl = NULL; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	int16_t *list = NULL; -	int16_t index = 0; -	call_frame_t *prev_frame = cookie; - -	if (op_ret == -1) { -		/* No need to send mknod request to other servers,  -		 * as namespace action failed  -		 */ -		gf_log (this->name, GF_LOG_ERROR,  -			"child(%s): path(%s): %s",  -			prev_frame->this->name, local->loc1.path,  -			strerror (op_errno)); -		unify_local_wipe (local); -		STACK_UNWIND (frame, op_ret, op_errno, inode, buf, -                              preparent, postparent); -		return 0; -	} -   -	/* Create one inode for this entry */ -	local->op_ret = 0; -	local->stbuf = *buf; -	local->ia_ino = buf->ia_ino; - -        local->oldpreparent = *preparent; -        local->oldpostparent = *postparent; - -	list = GF_CALLOC (1, sizeof (int16_t) * 3, gf_unify_mt_int16_t); -	ERR_ABORT (list); -	list[0] = priv->child_count; -	list[2] = -1; -	inode_ctx_put (inode, this, (uint64_t)(long)list); - -	sched_ops = priv->sched_ops; - -	/* Send mknod request to scheduled node now */ -	sched_xl = sched_ops->schedule (this, local->loc1.path);  -	if (!sched_xl) { -		gf_log (this->name, GF_LOG_ERROR,  -			"mknod failed on storage node, no node online " -			"at the moment, sending unlink to NS"); -		local->op_errno = ENOTCONN; -		STACK_WIND (frame, -			    unify_mknod_unlink_cbk, -			    NS(this), -			    NS(this)->fops->unlink, -			    &local->loc1); -       -		return 0; -	} - -	for (index = 0; index < priv->child_count; index++) -		if (sched_xl == priv->xl_array[index]) -			break; -	list[1] = index; -   -	STACK_WIND (frame,  unify_mknod_cbk, -		    sched_xl,  sched_xl->fops->mknod, -		    &local->loc1, local->mode, local->dev); - -	return 0; -} - -/** - * unify_mknod - Create a device on namespace first, and later create on  - *       the storage node. - */ -int32_t -unify_mknod (call_frame_t *frame, -	     xlator_t *this, -	     loc_t *loc, -	     mode_t mode, -	     dev_t rdev) -{ -	unify_local_t *local = NULL; -   -	/* Initialization */ -	INIT_LOCAL (frame, local); -	local->mode = mode; -	local->dev = rdev; -	loc_copy (&local->loc1, loc); -	if (local->loc1.path == NULL) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, loc->inode, NULL); -		return 0; -	} - -	STACK_WIND (frame, -		    unify_ns_mknod_cbk, -		    NS(this), -		    NS(this)->fops->mknod, -		    loc, -		    mode, -		    rdev); - -	return 0; -} - -int32_t  -unify_symlink_unlink_cbk (call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno, -                          struct iatt *preparent, -                          struct iatt *postparent) -{ -	unify_local_t *local = frame->local; -	if (op_ret == -1) -		gf_log (this->name, GF_LOG_ERROR,  -			"%s: %s", local->loc1.path, strerror (op_errno)); - -	unify_local_wipe (local); -	STACK_UNWIND (frame, -1, local->op_errno, NULL, NULL); -	return 0; -} - -/** - * unify_symlink_cbk -  - */ -int32_t -unify_symlink_cbk (call_frame_t *frame, -		   void *cookie, -		   xlator_t *this, -		   int32_t op_ret, -		   int32_t op_errno, -		   inode_t *inode, -                   struct iatt *buf, -                   struct iatt *preparent, -                   struct iatt *postparent) -{ -	unify_local_t *local = frame->local; - -	if (op_ret == -1) { -		/* Symlink on storage node failed, hence send unlink  -		   to the NS node */ -		local->op_errno = op_errno; -		gf_log (this->name, GF_LOG_ERROR,  -			"symlink on storage node failed, sending unlink " -			"to namespace"); - -		STACK_WIND (frame, -			    unify_symlink_unlink_cbk, -			    NS(this), -			    NS(this)->fops->unlink, -			    &local->loc1); -     -		return 0; -	} -   -	local->stbuf = *buf; -	local->stbuf.ia_ino = local->ia_ino; -	unify_local_wipe (local); -	STACK_UNWIND (frame, op_ret, op_errno, inode, &local->stbuf, -                      &local->oldpreparent, &local->oldpostparent); - -	return 0; -} - -/** - * unify_ns_symlink_cbk -  - */ -int32_t -unify_ns_symlink_cbk (call_frame_t *frame, -		      void *cookie, -		      xlator_t *this, -		      int32_t op_ret, -		      int32_t op_errno, -		      inode_t *inode, -                      struct iatt *buf, -                      struct iatt *preparent, -                      struct iatt *postparent) -{ - -	struct sched_ops *sched_ops = NULL; -	xlator_t *sched_xl = NULL; -	int16_t *list = NULL; -	unify_local_t *local = frame->local; -	unify_private_t *priv = this->private; -	int16_t index = 0; - -	if (op_ret == -1) { -		/* No need to send symlink request to other servers,  -		 * as namespace action failed  -		 */ -		gf_log (this->name, GF_LOG_ERROR,  -			"namespace: path(%s): %s",  -			local->loc1.path, strerror (op_errno)); -		unify_local_wipe (local); -		STACK_UNWIND (frame, op_ret, op_errno, NULL, buf, -                              preparent, postparent); -		return 0; -	} -   -	/* Create one inode for this entry */ -	local->op_ret = 0; -	local->ia_ino = buf->ia_ino; -   -        local->oldpreparent = *preparent; -        local->oldpostparent = *postparent; - -	/* Start the mapping list */ - -	list = GF_CALLOC (1, sizeof (int16_t) * 3, gf_unify_mt_int16_t); -	ERR_ABORT (list); -	list[0] = priv->child_count; //namespace's index -	list[2] = -1; -	inode_ctx_put (inode, this, (uint64_t)(long)list); - -	sched_ops = priv->sched_ops; - -	/* Send symlink request to all the nodes now */ -	sched_xl = sched_ops->schedule (this, local->loc1.path);  -	if (!sched_xl) { -		/* Symlink on storage node failed, hence send unlink  -		   to the NS node */ -		local->op_errno = ENOTCONN; -		gf_log (this->name, GF_LOG_ERROR,  -			"symlink on storage node failed, no node online, " -			"sending unlink to namespace"); -       -		STACK_WIND (frame, -			    unify_symlink_unlink_cbk, -			    NS(this), -			    NS(this)->fops->unlink, -			    &local->loc1); -       -		return 0; -	} - -	for (index = 0; index < priv->child_count; index++) -		if (sched_xl == priv->xl_array[index]) -			break; -	list[1] = index; -	 -	STACK_WIND (frame, -		    unify_symlink_cbk, -		    sched_xl, -		    sched_xl->fops->symlink, -		    local->name, -		    &local->loc1); - -	return 0; -} - -/** - * unify_symlink -  - */ -int32_t -unify_symlink (call_frame_t *frame, -	       xlator_t *this, -	       const char *linkpath, -	       loc_t *loc) -{ -	unify_local_t *local = NULL; -   -	/* Initialization */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, loc); -	local->name = gf_strdup (linkpath); - -	if ((local->name == NULL) ||  -	    (local->loc1.path == NULL)) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, loc->inode, NULL); -		return 0; -	} - -	STACK_WIND (frame, -		    unify_ns_symlink_cbk, -		    NS(this), -		    NS(this)->fops->symlink, -		    linkpath, -		    loc); - -	return 0; -} - - -int32_t  -unify_rename_unlink_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -                         struct iatt *preparent, -                         struct iatt *postparent) -{ -	int32_t callcnt = 0; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; -   -	if (op_ret == -1) { -		gf_log (this->name, GF_LOG_ERROR,  -			"child(%s): path(%s -> %s): %s",  -			prev_frame->this->name,  -			local->loc1.path, local->loc2.path,  -			strerror (op_errno)); -       -	} -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		local->stbuf.ia_ino = local->ia_ino; -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret, local->op_errno,  -			      &local->stbuf); -	} -	return 0; -} - -int32_t  -unify_ns_rename_undo_cbk (call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno, -			  struct iatt *buf, -                          struct iatt *preoldparent, -                          struct iatt *postoldparent, -                          struct iatt *prenewparent, -                          struct iatt *postnewparent) -{ -	unify_local_t *local = frame->local; - -	if (op_ret == -1) { -		gf_log (this->name, GF_LOG_ERROR,  -			"namespace: path(%s -> %s): %s",  -			local->loc1.path, local->loc2.path,  -			strerror (op_errno)); -	} - -	local->stbuf.ia_ino = local->ia_ino; -	unify_local_wipe (local); -	STACK_UNWIND (frame, local->op_ret, local->op_errno, &local->stbuf); -	return 0; -} - -int32_t  -unify_rename_cbk (call_frame_t *frame, -		  void *cookie, -		  xlator_t *this, -		  int32_t op_ret, -		  int32_t op_errno, -		  struct iatt *buf, -                  struct iatt *preoldparent, -                  struct iatt *postoldparent, -                  struct iatt *prenewparent, -                  struct iatt *postnewparent) -{ -	int32_t index = 0; -	int32_t callcnt = 0; -	int16_t *list = NULL; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	call_frame_t *prev_frame = cookie; -   -	LOCK (&frame->lock); -	{ -		callcnt = --local->call_count; -		if (op_ret >= 0) { -			if (!IA_ISDIR (buf->ia_type)) -				local->stbuf = *buf; -			local->op_ret = op_ret; -		} else { -			gf_log (this->name, GF_LOG_ERROR,  -				"child(%s): path(%s -> %s): %s",  -				prev_frame->this->name,  -				local->loc1.path, local->loc2.path,  -				strerror (op_errno)); -			local->op_errno = op_errno; -		} -	} -	UNLOCK (&frame->lock); - -	if (!callcnt) { -		local->stbuf.ia_ino = local->ia_ino; -		if (IA_ISDIR (local->loc1.inode->ia_type)) { -			unify_local_wipe (local); -			STACK_UNWIND (frame, local->op_ret, local->op_errno, -                                      &local->stbuf, &local->oldpreparent, -                                      &local->oldpostparent, &local->newpreparent, -                                      &local->newpostparent); -			return 0; -		} - -		if (local->op_ret == -1) { -			/* TODO: check this logic */ - -			/* Rename failed in storage node, successful on NS,  -			 * hence, rename back the entries in NS */ -			/* NOTE: this will be done only if the destination  -			 * doesn't exists, if  the destination exists, the  -			 * job of correcting NS is left to self-heal -			 */ -			if (!local->index) { -				loc_t tmp_oldloc = { -                                        /* its actual 'newloc->path' */ -					.path = local->loc2.path,  -					.inode = local->loc1.inode, -					.parent = local->loc2.parent -				}; -	 -				loc_t tmp_newloc = { -					/* Actual 'oldloc->path' */ -					.path = local->loc1.path, -					.parent = local->loc1.parent -				}; - -				gf_log (this->name, GF_LOG_ERROR,  -					"rename succussful on namespace, on " -					"stroage node failed, reverting back"); - -				STACK_WIND (frame, -					    unify_ns_rename_undo_cbk, -					    NS(this), -					    NS(this)->fops->rename, -					    &tmp_oldloc, -					    &tmp_newloc); -				return 0; -			} -		} else { -			/* Rename successful on storage nodes */ - -			int32_t idx = 0; -			int16_t *tmp_list = NULL; -			uint64_t tmp_list_int64 = 0; -			if (local->loc2.inode) { -				inode_ctx_get (local->loc2.inode,  -					       this, &tmp_list_int64); -				list = (int16_t *)(long)tmp_list_int64; - -			} - -			if (list) {				 -				for (index = 0; list[index] != -1; index++); -				tmp_list = GF_CALLOC (1, index * 2,  -                                                      gf_unify_mt_int16_t); -				memcpy (tmp_list, list, index * 2); - -				for (index = 0; list[index] != -1; index++) { -					/* TODO: Check this logic. */ -					/* If the destination file exists in  -					 * the same storage node where we sent -					 * 'rename' call, no need to send  -					 * unlink  -					 */ -					for (idx = 0;  -					     local->list[idx] != -1; idx++) { -						if (tmp_list[index] == local->list[idx]) { -							tmp_list[index] = priv->child_count; -							continue; -						} -					} -	   -					if (NS(this) != priv->xl_array[tmp_list[index]]) { -						local->call_count++; -						callcnt++; -					} -				} - -				if (local->call_count) { -					if (callcnt > 1) -						gf_log (this->name,  -							GF_LOG_ERROR,  -							"%s->%s: more (%d) " -							"subvolumes have the " -							"newloc entry",  -							local->loc1.path,  -							local->loc2.path,  -							callcnt); - -					for (index=0;  -					     tmp_list[index] != -1; index++) { -						if (NS(this) != priv->xl_array[tmp_list[index]]) {		     -							STACK_WIND (frame, -								    unify_rename_unlink_cbk, -								    priv->xl_array[tmp_list[index]], -								    priv->xl_array[tmp_list[index]]->fops->unlink, -								    &local->loc2); -							if (!--callcnt) -								break; -						} -					} - -					GF_FREE (tmp_list); -					return 0; -				} -				if (tmp_list) -					GF_FREE (tmp_list); -			} -		} -     -		/* Need not send 'unlink' to storage node */ -		unify_local_wipe (local); -		STACK_UNWIND (frame, local->op_ret,  -			      local->op_errno, &local->stbuf, -                              &local->oldpreparent, &local->oldpostparent, -                              &local->newpreparent, &local->newpostparent); -	} - -	return 0; -} - -int32_t  -unify_ns_rename_cbk (call_frame_t *frame, -		     void *cookie, -		     xlator_t *this, -		     int32_t op_ret, -		     int32_t op_errno, -		     struct iatt *buf, -                     struct iatt *preoldparent, -                     struct iatt *postoldparent, -                     struct iatt *prenewparent, -                     struct iatt *postnewparent) -{ -	int32_t index = 0; -	int32_t callcnt = 0; -	int16_t *list = NULL; -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; - -	if (op_ret == -1) { -		/* Free local->new_inode */ -		gf_log (this->name, GF_LOG_ERROR,  -			"namespace: path(%s -> %s): %s",  -			local->loc1.path, local->loc2.path,  -			strerror (op_errno)); - -		unify_local_wipe (local); -		STACK_UNWIND (frame, op_ret, op_errno, buf, -                              preoldparent, postoldparent, -                              prenewparent, postnewparent); -		return 0; -	} - -	local->stbuf = *buf; -	local->ia_ino = buf->ia_ino; - -        local->oldpreparent = *preoldparent; -        local->oldpostparent = *postoldparent; -        local->newpreparent = *prenewparent; -        local->newpostparent = *postnewparent; - -	/* Everything is fine. */ -	if (IA_ISDIR (buf->ia_type)) { -		local->call_count = priv->child_count; -		for (index=0; index < priv->child_count; index++) { -			STACK_WIND (frame, -				    unify_rename_cbk, -				    priv->xl_array[index], -				    priv->xl_array[index]->fops->rename, -				    &local->loc1, -				    &local->loc2); -		} - -		return 0; -	} - -	local->call_count = 0;   -	/* send rename */ -	list = local->list; -	for (index=0; list[index] != -1; index++) { -		if (NS(this) != priv->xl_array[list[index]]) { -			local->call_count++; -			callcnt++; -		} -	} - -	if (local->call_count) { -		for (index=0; list[index] != -1; index++) { -			if (NS(this) != priv->xl_array[list[index]]) { -				STACK_WIND (frame, -					    unify_rename_cbk, -					    priv->xl_array[list[index]], -					    priv->xl_array[list[index]]->fops->rename, -					    &local->loc1, -					    &local->loc2); -				if (!--callcnt) -					break; -			} -		} -	} else { -		/* file doesn't seem to be present in storage nodes */ -		gf_log (this->name, GF_LOG_CRITICAL, -			"CRITICAL: source file not in storage node, " -			"rename successful on namespace :O"); -		unify_local_wipe (local); -		STACK_UNWIND (frame, -1, EIO, NULL, -                              NULL, NULL, /* preoldparent, postoldparent */ -                              NULL, NULL); /* prenewparent, postnewparent */ -	} -	return 0; -} - - -/** - * unify_rename - One of the tricky function. The deadliest of all :O - */ -int32_t -unify_rename (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *oldloc, -	      loc_t *newloc) -{ -	unify_local_t *local = NULL; -  	uint64_t tmp_list = 0; - -	/* Initialization */ -	INIT_LOCAL (frame, local); -	loc_copy (&local->loc1, oldloc); -	loc_copy (&local->loc2, newloc); - -	if ((local->loc1.path == NULL) ||  -	    (local->loc2.path == NULL)) { -		gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O"); -		STACK_UNWIND (frame, -1, ENOMEM, NULL, -                              NULL, NULL, /* preoldparent, postoldparent */ -                              NULL, NULL); /* prenewparent, postnewparent */ -		return 0; -	} -   -	inode_ctx_get (oldloc->inode, this, &tmp_list); -	local->list = (int16_t *)(long)tmp_list; - -	STACK_WIND (frame, -		    unify_ns_rename_cbk, -		    NS(this), -		    NS(this)->fops->rename, -		    oldloc, -		    newloc); -	return 0; -} - -/** - * unify_link_cbk - - */ -int32_t -unify_link_cbk (call_frame_t *frame, -		void *cookie, -		xlator_t *this, -		int32_t op_ret, -		int32_t op_errno, -		inode_t *inode, -                struct iatt *buf, -                struct iatt *preparent, -                struct iatt *postparent) -{ -	unify_local_t *local = frame->local; - -	if (op_ret >= 0)  -		local->stbuf = *buf; -	local->stbuf.ia_ino = local->ia_ino; - -	unify_local_wipe (local); -	STACK_UNWIND (frame, op_ret, op_errno, inode, &local->stbuf, -                      &local->oldpreparent, &local->oldpostparent); - -	return 0; -} - -/** - * unify_ns_link_cbk -  - */ -int32_t -unify_ns_link_cbk (call_frame_t *frame, -		   void *cookie, -		   xlator_t *this, -		   int32_t op_ret, -		   int32_t op_errno, -		   inode_t *inode, -                   struct iatt *buf, -                   struct iatt *preparent, -                   struct iatt *postparent) -{ -	unify_private_t *priv = this->private; -	unify_local_t *local = frame->local; -	int16_t *list = local->list; -	int16_t index = 0; - -	if (op_ret == -1) { -		/* No need to send link request to other servers,  -		 * as namespace action failed  -		 */ -		gf_log (this->name, GF_LOG_ERROR,  -			"namespace: path(%s -> %s): %s",  -			local->loc1.path, local->loc2.path,  -			strerror (op_errno)); -		unify_local_wipe (local); -		STACK_UNWIND (frame, op_ret, op_errno, inode, buf, -                              preparent, postparent); -		return 0; -	} - -	/* Update inode for this entry */ -	local->op_ret = 0; -	local->ia_ino = buf->ia_ino; - -        local->oldpreparent = *preparent; -        local->oldpostparent = *postparent; - -	/* Send link request to the node now */ -	for (index = 0; list[index] != -1; index++) { -		char need_break = (list[index+1] == -1); -		if (priv->xl_array[list[index]] != NS (this)) { -			STACK_WIND (frame, -				    unify_link_cbk, -				    priv->xl_array[list[index]], -				    priv->xl_array[list[index]]->fops->link, -				    &local->loc1, -				    &local->loc2); -                        break; -		} -		if (need_break) -			break; -	} - -	return 0; -} - -/** - * unify_link -  - */ -int32_t -unify_link (call_frame_t *frame, -	    xlator_t *this, -	    loc_t *oldloc, -	    loc_t *newloc) -{ -	unify_local_t *local = NULL; -  	uint64_t tmp_list = 0; - -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (oldloc); -	UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (newloc); - -	/* Initialization */ -	INIT_LOCAL (frame, local); - -	loc_copy (&local->loc1, oldloc); -	loc_copy (&local->loc2, newloc); - -	inode_ctx_get (oldloc->inode, this, &tmp_list); -	local->list = (int16_t *)(long)tmp_list; - -	STACK_WIND (frame, -		    unify_ns_link_cbk, -		    NS(this), -		    NS(this)->fops->link, -		    oldloc, -		    newloc); - -	return 0; -} - - -/** - * unify_checksum_cbk -  - */ -int32_t -unify_checksum_cbk (call_frame_t *frame, -		    void *cookie, -		    xlator_t *this, -		    int32_t op_ret, -		    int32_t op_errno, -		    uint8_t *fchecksum, -		    uint8_t *dchecksum) -{ -	STACK_UNWIND (frame, op_ret, op_errno, fchecksum, dchecksum); - -	return 0; -} - -/** - * unify_checksum -  - */ -int32_t -unify_checksum (call_frame_t *frame, -		xlator_t *this, -		loc_t *loc, -		int32_t flag) -{ -	STACK_WIND (frame, -		    unify_checksum_cbk, -		    NS(this), -		    NS(this)->fops->checksum, -		    loc, -		    flag); - -	return 0; -} - - -/** - * unify_finodelk_cbk -  - */ -int -unify_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -		    int32_t op_ret, int32_t op_errno) -{ -	STACK_UNWIND (frame, op_ret, op_errno); -	return 0; -} - -/** - * unify_finodelk - */ -int -unify_finodelk (call_frame_t *frame, xlator_t *this, -		const char *volume, fd_t *fd, int cmd, struct gf_flock *flock) -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, unify_finodelk_cbk, -		    child, child->fops->finodelk, -		    volume, fd, cmd, flock); - -	return 0; -} - - - -/** - * unify_fentrylk_cbk -  - */ -int -unify_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -		    int32_t op_ret, int32_t op_errno) -{ -	STACK_UNWIND (frame, op_ret, op_errno); -	return 0; -} - -/** - * unify_fentrylk - */ -int -unify_fentrylk (call_frame_t *frame, xlator_t *this, -		const char *volume, fd_t *fd, const char *basename, -		entrylk_cmd cmd, entrylk_type type) -		 -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, unify_fentrylk_cbk, -		    child, child->fops->fentrylk, -		    volume, fd, basename, cmd, type); - -	return 0; -} - - - -/** - * unify_fxattrop_cbk -  - */ -int -unify_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -		    int32_t op_ret, int32_t op_errno, dict_t *xattr) -{ -	STACK_UNWIND (frame, op_ret, op_errno, xattr); -	return 0; -} - -/** - * unify_fxattrop - */ -int -unify_fxattrop (call_frame_t *frame, xlator_t *this, -		fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr) -{ -	UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd); -	xlator_t *child = NULL; -	uint64_t tmp_child = 0; - -	fd_ctx_get (fd, this, &tmp_child); -	child = (xlator_t *)(long)tmp_child;		      - -	STACK_WIND (frame, unify_fxattrop_cbk, -		    child, child->fops->fxattrop, -		    fd, optype, xattr); - -	return 0; -} - - -/** - * unify_inodelk_cbk -  - */ -int -unify_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -		   int32_t op_ret, int32_t op_errno) -{ -	STACK_UNWIND (frame, op_ret, op_errno); -	return 0; -} - - -/** - * unify_inodelk - */ -int -unify_inodelk (call_frame_t *frame, xlator_t *this, -	       const char *volume, loc_t *loc, int cmd, struct gf_flock *flock) -{ -	xlator_t *child = NULL; - -	child = unify_loc_subvol (loc, this); - -	STACK_WIND (frame, unify_inodelk_cbk, -		    child, child->fops->inodelk, -		    volume, loc, cmd, flock); - -	return 0; -} - - - -/** - * unify_entrylk_cbk -  - */ -int -unify_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -		   int32_t op_ret, int32_t op_errno) -{ -	STACK_UNWIND (frame, op_ret, op_errno); -	return 0; -} - -/** - * unify_entrylk - */ -int -unify_entrylk (call_frame_t *frame, xlator_t *this, -	       const char *volume, loc_t *loc, const char *basename, -	       entrylk_cmd cmd, entrylk_type type) -		 -{ -	xlator_t *child = NULL; - -	child = unify_loc_subvol (loc, this); - -	STACK_WIND (frame, unify_entrylk_cbk, -		    child, child->fops->entrylk, -		    volume, loc, basename, cmd, type); - -	return 0; -} - - - -/** - * unify_xattrop_cbk -  - */ -int -unify_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -		   int32_t op_ret, int32_t op_errno, dict_t *xattr) -{ -	STACK_UNWIND (frame, op_ret, op_errno, xattr); -	return 0; -} - -/** - * unify_xattrop - */ -int -unify_xattrop (call_frame_t *frame, xlator_t *this, -		loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr) -{ -	xlator_t *child = NULL; - -	child = unify_loc_subvol (loc, this); - -	STACK_WIND (frame, unify_xattrop_cbk, -		    child, child->fops->xattrop, -		    loc, optype, xattr); - -	return 0; -} - -int -unify_forget (xlator_t *this, -              inode_t *inode) -{ -        int16_t *list = NULL; -        uint64_t tmp_list = 0; - -        if (inode->ia_type && (!IA_ISDIR(inode->ia_type))) { -                inode_ctx_get (inode, this, &tmp_list); -                if (tmp_list) { -                        list = (int16_t *)(long)tmp_list; -                        GF_FREE (list); -                } -        } - -        return 0; -} - -/** - * notify - */ -int32_t -notify (xlator_t *this, -        int32_t event, -        void *data, -        ...) -{ -	unify_private_t *priv = this->private; -	struct sched_ops *sched = NULL; - -	if (!priv) { -		return 0; -	} - -	sched = priv->sched_ops;     -	if (!sched) { -		gf_log (this->name, GF_LOG_CRITICAL, "No scheduler :O"); -		raise (SIGTERM); -		return 0; -	} -	if (priv->namespace == data) { -		if (event == GF_EVENT_CHILD_UP) { -			sched->notify (this, event, data); -		} -		return 0; -	} - -	switch (event) -	{ -	case GF_EVENT_CHILD_UP: -	{ -		/* Call scheduler's update () to enable it for scheduling */ -		sched->notify (this, event, data); -	 -		LOCK (&priv->lock); -		{ -			/* Increment the inode's generation, which is  -			   used for self_heal */ -			++priv->inode_generation; -			++priv->num_child_up; -		} -		UNLOCK (&priv->lock); - -		if (!priv->is_up) { -			default_notify (this, event, data); -			priv->is_up = 1; -		} -	} -	break; -	case GF_EVENT_CHILD_DOWN: -	{ -		/* Call scheduler's update () to disable the child node  -		 * for scheduling -		 */ -		sched->notify (this, event, data); -		LOCK (&priv->lock); -		{ -			--priv->num_child_up; -		} -		UNLOCK (&priv->lock); - -		if (priv->num_child_up == 0) { -			/* Send CHILD_DOWN to upper layer */ -			default_notify (this, event, data); -			priv->is_up = 0; -		} -	} -	break; - -	default: -	{ -		default_notify (this, event, data); -	} -	break; -	} - -	return 0; -} - -int32_t -mem_acct_init (xlator_t *this) -{ -        int     ret = -1; - -        if (!this) -                return ret; - -        ret = xlator_mem_acct_init (this, gf_unify_mt_end + 1); -         -        if (ret != 0) { -                gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" -                                "failed"); -                return ret; -        } - -        return ret; -} - -/**  - * init - This function is called first in the xlator, while initializing. - *   All the config file options are checked and appropriate flags are set. - * - * @this -  - */ -int32_t  -init (xlator_t *this) -{ -	int32_t          ret       = 0; -	int32_t          count     = 0; -	data_t          *scheduler = NULL; -	data_t          *data      = NULL; -	xlator_t        *ns_xl     = NULL; -	xlator_list_t   *trav      = NULL; -	xlator_list_t   *xlparent  = NULL; -	xlator_list_t   *parent    = NULL; -	unify_private_t *_private  = NULL;  - - -	/* Check for number of child nodes, if there is no child nodes, exit */ -	if (!this->children) { -		gf_log (this->name, GF_LOG_ERROR, -			"No child nodes specified. check \"subvolumes \" " -			"option in volfile"); -		return -1; -	} - -  	if (!this->parents) { -		gf_log (this->name, GF_LOG_WARNING, -			"dangling volume. check volfile "); -	} -   -	/* Check for 'scheduler' in volume */ -	scheduler = dict_get (this->options, "scheduler"); -	if (!scheduler) { -		gf_log (this->name, GF_LOG_ERROR,  -			"\"option scheduler <x>\" is missing in volfile"); -		return -1; -	} - -	/* Setting "option namespace <node>" */ -	data = dict_get (this->options, "namespace"); -	if(!data) { -		gf_log (this->name, GF_LOG_CRITICAL,  -			"namespace option not specified, Exiting"); -		return -1; -	} -	/* Search namespace in the child node, if found, exit */ -	trav = this->children; -	while (trav) { -		if (strcmp (trav->xlator->name, data->data) == 0) -			break; -		trav = trav->next; -	} -	if (trav) { -		gf_log (this->name, GF_LOG_CRITICAL,  -			"namespace node used as a subvolume, Exiting"); -		return -1; -	} -	 -	/* Search for the namespace node, if found, continue */ -	ns_xl = this->next; -	while (ns_xl) { -		if (strcmp (ns_xl->name, data->data) == 0) -			break; -		ns_xl = ns_xl->next; -	} -	if (!ns_xl) { -		gf_log (this->name, GF_LOG_CRITICAL,  -			"namespace node not found in volfile, Exiting"); -		return -1; -	} -	 -	gf_log (this->name, GF_LOG_DEBUG,  -		"namespace node specified as %s", data->data); -	 -	_private = GF_CALLOC (1, sizeof (*_private),  -                              gf_unify_mt_unify_private_t); -	ERR_ABORT (_private); -	_private->sched_ops = get_scheduler (this, scheduler->data); -	if (!_private->sched_ops) { -		gf_log (this->name, GF_LOG_CRITICAL,  -			"Error while loading scheduler. Exiting"); -		GF_FREE (_private); -		return -1; -	} -	 -	if (ns_xl->parents) { -		gf_log (this->name, GF_LOG_CRITICAL, -			"Namespace node should not be a child of any other node. Exiting"); -		GF_FREE (_private); -		return -1; -	} - -	_private->namespace = ns_xl; -	 -	/* update _private structure */ -	{ -		count = 0; -		trav = this->children; -		/* Get the number of child count */ -		while (trav) { -			count++; -			trav = trav->next; -		} -		 -		gf_log (this->name, GF_LOG_DEBUG,  -			"Child node count is %d", count);     - -		_private->child_count = count; -		if (count == 1) { -			/* TODO: Should I error out here? */ -			gf_log (this->name, GF_LOG_CRITICAL,  -				"WARNING: You have defined only one " -				"\"subvolumes\" for unify volume. It may not " -				"be the desired config, review your volume " -				"volfile. If this is how you are testing it," -				" you may hit some performance penalty"); -		} -		 -		_private->xl_array = GF_CALLOC (1,  -					        sizeof (xlator_t) * (count + 1), -                                                gf_unify_mt_xlator_t); -		ERR_ABORT (_private->xl_array); -		 -		count = 0; -		trav = this->children; -		while (trav) { -			_private->xl_array[count++] = trav->xlator; -			trav = trav->next; -		} -		_private->xl_array[count] = _private->namespace; -		 -		/* self-heal part, start with generation '1' */ -		_private->inode_generation = 1;  -                /* Because, Foreground part is tested well */ -		_private->self_heal = ZR_UNIFY_FG_SELF_HEAL;  -		data = dict_get (this->options, "self-heal"); -		if (data) { -			if (strcasecmp (data->data, "off") == 0)  -				_private->self_heal = ZR_UNIFY_SELF_HEAL_OFF; - -			if (strcasecmp (data->data, "foreground") == 0) -				_private->self_heal = ZR_UNIFY_FG_SELF_HEAL; - -			if (strcasecmp (data->data, "background") == 0) -				_private->self_heal = ZR_UNIFY_BG_SELF_HEAL; -		} -     -		/* optimist - ask bulde for more about it */ -		data = dict_get (this->options, "optimist"); -		if (data) { -			if (gf_string2boolean (data->data,  -					       &_private->optimist) == -1) { -				gf_log (this->name, GF_LOG_ERROR,  -					"optimist excepts only boolean " -					"options"); -			} -		} - -		LOCK_INIT (&_private->lock); -	} - -	/* Now that everything is fine. */ -	this->private = (void *)_private; -	{ -                ret = _private->sched_ops->mem_acct_init (this); - -                if (ret == -1) { -                        return -1; -                } - -		/* Initialize scheduler, if everything else is successful */ -		ret = _private->sched_ops->init (this);  -		if (ret == -1) { -			gf_log (this->name, GF_LOG_CRITICAL, -				"Initializing scheduler failed, Exiting"); -			GF_FREE (_private); -			return -1; -		} - - -		ret = 0; - -		/* This section is required because some fops may look  -		 * for 'xl->parent' variable  -		 */ -		xlparent = GF_CALLOC (1, sizeof (*xlparent), -                                      gf_unify_mt_xlator_list_t); -		xlparent->xlator = this; -		if (!ns_xl->parents) { -			ns_xl->parents = xlparent; -		} else { -			parent = ns_xl->parents; -			while (parent->next) -				parent = parent->next; -			parent->next = xlparent; -		} -	} - -	/* Tell namespace node that init is done */ -	xlator_notify (ns_xl, GF_EVENT_PARENT_UP, this); - -	return 0; -} - -/**  - * fini  - Free all the allocated memory  - */ -void -fini (xlator_t *this) -{ -	unify_private_t *priv = this->private; -	priv->sched_ops->fini (this); -	this->private = NULL; -	LOCK_DESTROY (&priv->lock); -	GF_FREE (priv->xl_array); -	GF_FREE (priv); -	return; -} - - -struct xlator_fops fops = { -	.stat        = unify_stat, -	.readlink    = unify_readlink, -	.mknod       = unify_mknod, -	.mkdir       = unify_mkdir, -	.unlink      = unify_unlink, -	.rmdir       = unify_rmdir, -	.symlink     = unify_symlink, -	.rename      = unify_rename, -	.link        = unify_link, -	.truncate    = unify_truncate, -	.create      = unify_create, -	.open        = unify_open, -	.readv       = unify_readv, -	.writev      = unify_writev, -	.statfs      = unify_statfs, -	.flush       = unify_flush, -	.fsync       = unify_fsync, -	.setxattr    = unify_setxattr, -	.getxattr    = unify_getxattr, -	.removexattr = unify_removexattr, -	.opendir     = unify_opendir, -	.readdir     = unify_readdir, -	.readdirp    = unify_readdirp, -	.fsyncdir    = unify_fsyncdir, -	.access      = unify_access, -	.ftruncate   = unify_ftruncate, -	.fstat       = unify_fstat, -	.lk          = unify_lk, -	.lookup      = unify_lookup, -	.getdents    = unify_getdents, -	.checksum    = unify_checksum, -	.inodelk     = unify_inodelk, -	.finodelk    = unify_finodelk, -	.entrylk     = unify_entrylk, -	.fentrylk    = unify_fentrylk, -	.xattrop     = unify_xattrop, -	.fxattrop    = unify_fxattrop, -        .setattr     = unify_setattr,  -        .fsetattr    = unify_fsetattr, -}; - - -struct xlator_cbks cbks = { -        .forget  = unify_forget, -}; - -struct volume_options options[] = { -	{ .key   = { "namespace" },   -	  .type  = GF_OPTION_TYPE_XLATOR  -	}, -	{ .key   = { "scheduler" },   -	  .value = { "alu", "rr", "random", "nufa", "switch" }, -	  .type  = GF_OPTION_TYPE_STR -	}, -	{ .key   = {"self-heal"},   -	  .value = { "foreground", "background", "off" }, -	  .type  = GF_OPTION_TYPE_STR -	}, -	/* TODO: remove it some time later */ -	{ .key   = {"optimist"},   -	  .type  = GF_OPTION_TYPE_BOOL  -	}, - -	{ .key   = {NULL} }, -}; diff --git a/xlators/cluster/unify/src/unify.h b/xlators/cluster/unify/src/unify.h deleted file mode 100644 index dbd5e44a2f1..00000000000 --- a/xlators/cluster/unify/src/unify.h +++ /dev/null @@ -1,146 +0,0 @@ -/* -  Copyright (c) 2006-2011 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/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#ifndef _UNIFY_H -#define _UNIFY_H - -#include "scheduler.h" -#include "list.h" -#include "unify-mem-types.h" - -#define MAX_DIR_ENTRY_STRING     (32 * 1024) - -#define ZR_UNIFY_SELF_HEAL_OFF 0 -#define ZR_UNIFY_FG_SELF_HEAL  1 -#define ZR_UNIFY_BG_SELF_HEAL  2 - -/* Sometimes one should use completely random numbers.. its good :p */ -#define UNIFY_SELF_HEAL_GETDENTS_COUNT 512 - -#define NS(xl)          (((unify_private_t *)xl->private)->namespace) - -/* This is used to allocate memory for local structure */ -#define INIT_LOCAL(fr, loc)                   \ -do {                                          \ -  loc = GF_CALLOC (1, sizeof (unify_local_t), gf_unify_mt_unify_local_t);   \ -  ERR_ABORT (loc);			      \ -  if (!loc) {                                 \ -    STACK_UNWIND (fr, -1, ENOMEM);            \ -    return 0;                                 \ -  }                                           \ -  fr->local = loc;                            \ -  loc->op_ret = -1;                           \ -  loc->op_errno = ENOENT;                     \ -} while (0) - - - -struct unify_private { -	/* Update this structure depending on requirement */ -	void *scheduler;               /* THIS SHOULD BE THE FIRST VARIABLE,  -					  if xlator is using scheduler */ -	struct sched_ops *sched_ops;   /* Scheduler options  */ -	xlator_t *namespace;           /* ptr to namespace xlator */ -	xlator_t **xl_array; -	gf_boolean_t optimist; -	int16_t child_count; -	int16_t num_child_up; -	uint8_t self_heal; -	uint8_t is_up; -	uint64_t inode_generation; -	gf_lock_t lock; -}; -typedef struct unify_private unify_private_t; - -struct unify_self_heal_struct { -	uint8_t dir_checksum[NAME_MAX]; -	uint8_t ns_dir_checksum[NAME_MAX]; -	uint8_t file_checksum[NAME_MAX]; -	uint8_t ns_file_checksum[NAME_MAX]; -	off_t *offset_list; -	int   *count_list; -	dir_entry_t **entry_list; -}; - - -struct _unify_local_t { -	int32_t call_count; -	int32_t op_ret; -	int32_t op_errno; -	mode_t mode; -	off_t offset; -	dev_t dev; -	uid_t uid; -	gid_t gid; -	int32_t flags; -	int32_t entry_count; -	int32_t count;    // dir_entry_t count; -	fd_t *fd; -	struct iatt stbuf; -        struct iatt stpre; -        struct iatt stpost; -	struct statvfs statvfs_buf; -	struct timespec tv[2]; -	char *name; -	int32_t revalidate; - -	ino_t ia_ino; -	nlink_t ia_nlink; -   -	dict_t *dict; - -	int16_t *list; -	int16_t *new_list; /* Used only in case of rename */ -	int16_t index; - -	int32_t failed; -	int32_t return_eio;  /* Used in case of different st-mode  -				present for a given path */ - -	uint64_t inode_generation; /* used to store the per directory  -				    * inode_generation. Got from inode's ctx  -				    * of directory inodes -				    */ - -	struct unify_self_heal_struct *sh_struct; -	loc_t loc1, loc2; - -        struct iatt poststbuf; -        /* When not used for rename, old* -         * are used as the attrs for the current -         * parent directory. -         */ -        struct iatt oldpreparent; -        struct iatt oldpostparent; -        struct iatt newpreparent; -        struct iatt newpostparent; -        int32_t wbflags; -}; -typedef struct _unify_local_t unify_local_t; - -int32_t zr_unify_self_heal (call_frame_t *frame, -			    xlator_t *this, -			    unify_local_t *local); - -#endif /* _UNIFY_H */  | 
