summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/glusterfs.vol.sample53
-rw-r--r--doc/glusterfsd.vol.sample44
-rw-r--r--libglusterfsclient/Makefile.am3
-rw-r--r--libglusterfsclient/src/Makefile.am16
-rw-r--r--libglusterfsclient/src/libglusterfsclient-dentry.c404
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient-internals.h289
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.c8161
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.h1363
-rw-r--r--scheduler/Makefile.am3
-rw-r--r--scheduler/alu/Makefile.am3
-rw-r--r--scheduler/alu/src/Makefile.am14
-rw-r--r--scheduler/alu/src/alu-mem-types.h35
-rw-r--r--scheduler/alu/src/alu.c1019
-rw-r--r--scheduler/alu/src/alu.h89
-rw-r--r--scheduler/nufa/Makefile.am3
-rw-r--r--scheduler/nufa/src/Makefile.am12
-rw-r--r--scheduler/nufa/src/nufa-mem-types.h33
-rw-r--r--scheduler/nufa/src/nufa.c429
-rw-r--r--scheduler/random/Makefile.am3
-rw-r--r--scheduler/random/src/Makefile.am14
-rw-r--r--scheduler/random/src/random-mem-types.h32
-rw-r--r--scheduler/random/src/random.c305
-rw-r--r--scheduler/random/src/random.h46
-rw-r--r--scheduler/rr/Makefile.am3
-rw-r--r--scheduler/rr/src/Makefile.am13
-rw-r--r--scheduler/rr/src/rr-mem-types.h32
-rw-r--r--scheduler/rr/src/rr-options.c256
-rw-r--r--scheduler/rr/src/rr-options.h34
-rw-r--r--scheduler/rr/src/rr.c567
-rw-r--r--scheduler/rr/src/rr.h70
-rw-r--r--scheduler/switch/Makefile.am3
-rw-r--r--scheduler/switch/src/Makefile.am12
-rw-r--r--scheduler/switch/src/switch-mem-types.h33
-rw-r--r--scheduler/switch/src/switch.c451
-rw-r--r--xlators/cluster/unify/Makefile.am3
-rw-r--r--xlators/cluster/unify/src/Makefile.am16
-rw-r--r--xlators/cluster/unify/src/unify-mem-types.h41
-rw-r--r--xlators/cluster/unify/src/unify-self-heal.c1239
-rw-r--r--xlators/cluster/unify/src/unify.c4589
-rw-r--r--xlators/cluster/unify/src/unify.h146
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 */