summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
Diffstat (limited to 'xlators')
-rw-r--r--xlators/storage/posix/src/Makefile.am2
-rw-r--r--xlators/storage/posix/src/posix-helpers.c887
-rw-r--r--xlators/storage/posix/src/posix.c835
-rw-r--r--xlators/storage/posix/src/posix.h20
4 files changed, 913 insertions, 831 deletions
diff --git a/xlators/storage/posix/src/Makefile.am b/xlators/storage/posix/src/Makefile.am
index b8d1668ae..90ea1fd51 100644
--- a/xlators/storage/posix/src/Makefile.am
+++ b/xlators/storage/posix/src/Makefile.am
@@ -4,7 +4,7 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/storage
posix_la_LDFLAGS = -module -avoidversion
-posix_la_SOURCES = posix.c
+posix_la_SOURCES = posix.c posix-helpers.c
posix_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = posix.h posix-mem-types.h
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
new file mode 100644
index 000000000..7b130d4b9
--- /dev/null
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -0,0 +1,887 @@
+/*
+ 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 Affero 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
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero 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
+
+#define __XOPEN_SOURCE 500
+
+#include <stdint.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <errno.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <ftw.h>
+#include <sys/stat.h>
+
+#ifndef GF_BSD_HOST_OS
+#include <alloca.h>
+#endif /* GF_BSD_HOST_OS */
+
+#include "glusterfs.h"
+#include "md5.h"
+#include "checksum.h"
+#include "dict.h"
+#include "logging.h"
+#include "posix.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+#include "compat.h"
+#include "byte-order.h"
+#include "syscall.h"
+#include "statedump.h"
+#include "locking.h"
+#include "timer.h"
+#include "glusterfs3-xdr.h"
+#include "hashfn.h"
+
+
+typedef struct {
+ xlator_t *this;
+ const char *real_path;
+ dict_t *xattr;
+ struct iatt *stbuf;
+ loc_t *loc;
+} posix_xattr_filler_t;
+
+
+static void
+_posix_xattr_get_set (dict_t *xattr_req,
+ char *key,
+ data_t *data,
+ void *xattrargs)
+{
+ posix_xattr_filler_t *filler = xattrargs;
+ char *value = NULL;
+ ssize_t xattr_size = -1;
+ int ret = -1;
+ char *databuf = NULL;
+ int _fd = -1;
+ loc_t *loc = NULL;
+ ssize_t req_size = 0;
+
+
+ if (!strcmp (key, "gfid-req"))
+ return;
+ /* should size be put into the data_t ? */
+ if (!strcmp (key, GF_CONTENT_KEY)
+ && IA_ISREG (filler->stbuf->ia_type)) {
+
+ /* file content request */
+ req_size = data_to_uint64 (data);
+ if (req_size >= filler->stbuf->ia_size) {
+ _fd = open (filler->real_path, O_RDONLY);
+ if (_fd == -1) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "Opening file %s failed: %s",
+ filler->real_path, strerror (errno));
+ goto err;
+ }
+
+ databuf = GF_CALLOC (1, filler->stbuf->ia_size,
+ gf_posix_mt_char);
+ if (!databuf) {
+ goto err;
+ }
+
+ ret = read (_fd, databuf, filler->stbuf->ia_size);
+ if (ret == -1) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "Read on file %s failed: %s",
+ filler->real_path, strerror (errno));
+ goto err;
+ }
+
+ ret = close (_fd);
+ _fd = -1;
+ if (ret == -1) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "Close on file %s failed: %s",
+ filler->real_path, strerror (errno));
+ goto err;
+ }
+
+ ret = dict_set_bin (filler->xattr, key,
+ databuf, filler->stbuf->ia_size);
+ if (ret < 0) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "failed to set dict value. key: %s, path: %s",
+ key, filler->real_path);
+ goto err;
+ }
+
+ /* To avoid double free in cleanup below */
+ databuf = NULL;
+ err:
+ if (_fd != -1)
+ close (_fd);
+ if (databuf)
+ GF_FREE (databuf);
+ }
+ } else if (!strcmp (key, GLUSTERFS_OPEN_FD_COUNT)) {
+ loc = filler->loc;
+ if (!list_empty (&loc->inode->fd_list)) {
+ ret = dict_set_uint32 (filler->xattr, key, 1);
+ if (ret < 0)
+ gf_log (filler->this->name, GF_LOG_WARNING,
+ "Failed to set dictionary value for %s",
+ key);
+ } else {
+ ret = dict_set_uint32 (filler->xattr, key, 0);
+ if (ret < 0)
+ gf_log (filler->this->name, GF_LOG_WARNING,
+ "Failed to set dictionary value for %s",
+ key);
+ }
+ } else {
+ xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0);
+
+ if (xattr_size > 0) {
+ value = GF_CALLOC (1, xattr_size + 1,
+ gf_posix_mt_char);
+ if (!value)
+ return;
+
+ sys_lgetxattr (filler->real_path, key, value,
+ xattr_size);
+
+ value[xattr_size] = '\0';
+ ret = dict_set_bin (filler->xattr, key,
+ value, xattr_size);
+ if (ret < 0)
+ gf_log (filler->this->name, GF_LOG_DEBUG,
+ "dict set failed. path: %s, key: %s",
+ filler->real_path, key);
+ }
+ }
+}
+
+
+int
+posix_fill_gfid_path (xlator_t *this, const char *path, struct iatt *iatt)
+{
+ int ret = 0;
+
+ if (!iatt)
+ return 0;
+
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, iatt->ia_gfid, 16);
+ /* Return value of getxattr */
+ if (ret == 16)
+ ret = 0;
+
+ return ret;
+}
+
+
+int
+posix_fill_gfid_fd (xlator_t *this, int fd, struct iatt *iatt)
+{
+ int ret = 0;
+
+ if (!iatt)
+ return 0;
+
+ ret = sys_fgetxattr (fd, GFID_XATTR_KEY, iatt->ia_gfid, 16);
+ /* Return value of getxattr */
+ if (ret == 16)
+ ret = 0;
+
+ return ret;
+}
+
+void
+posix_fill_ino_from_gfid (xlator_t *this, struct iatt *buf)
+{
+ uint64_t temp_ino = 0;
+ int j = 0;
+ int i = 0;
+
+ /* consider least significant 8 bytes of value out of gfid */
+ for (i = 15; i > (15 - 8); i--) {
+ temp_ino += buf->ia_gfid[i] << j;
+ j += 8;
+ }
+
+ buf->ia_ino = temp_ino;
+}
+
+int
+posix_lstat_with_gfid (xlator_t *this, const char *path, struct iatt *stbuf_p)
+{
+ struct posix_private *priv = NULL;
+ int ret = 0;
+ struct stat lstatbuf = {0, };
+ struct iatt stbuf = {0, };
+
+ priv = this->private;
+
+ ret = lstat (path, &lstatbuf);
+ if (ret == -1)
+ goto out;
+
+ iatt_from_stat (&stbuf, &lstatbuf);
+
+ ret = posix_fill_gfid_path (this, path, &stbuf);
+ if (ret)
+ gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
+
+ posix_fill_ino_from_gfid (this, &stbuf);
+
+ if (stbuf_p)
+ *stbuf_p = stbuf;
+out:
+ return ret;
+}
+
+
+int
+posix_fstat_with_gfid (xlator_t *this, int fd, struct iatt *stbuf_p)
+{
+ struct posix_private *priv = NULL;
+ int ret = 0;
+ struct stat fstatbuf = {0, };
+ struct iatt stbuf = {0, };
+
+ priv = this->private;
+
+ ret = fstat (fd, &fstatbuf);
+ if (ret == -1)
+ goto out;
+
+ iatt_from_stat (&stbuf, &fstatbuf);
+
+ ret = posix_fill_gfid_fd (this, fd, &stbuf);
+ if (ret)
+ gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
+
+ posix_fill_ino_from_gfid (this, &stbuf);
+
+ if (stbuf_p)
+ *stbuf_p = stbuf;
+
+out:
+ return ret;
+}
+
+
+dict_t *
+posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc,
+ dict_t *xattr_req, struct iatt *buf)
+{
+ dict_t *xattr = NULL;
+ posix_xattr_filler_t filler = {0, };
+
+ xattr = get_new_dict();
+ if (!xattr) {
+ goto out;
+ }
+
+ filler.this = this;
+ filler.real_path = real_path;
+ filler.xattr = xattr;
+ filler.stbuf = buf;
+ filler.loc = loc;
+
+ dict_foreach (xattr_req, _posix_xattr_get_set, &filler);
+out:
+ return xattr;
+}
+
+
+/*
+ * If the parent directory of {real_path} has the setgid bit set,
+ * then set {gid} to the gid of the parent. Otherwise,
+ * leave {gid} unchanged.
+ */
+
+int
+setgid_override (xlator_t *this, char *real_path, gid_t *gid)
+{
+ char * tmp_path = NULL;
+ char * parent_path = NULL;
+ struct iatt parent_stbuf;
+
+ int op_ret = 0;
+
+ tmp_path = gf_strdup (real_path);
+ if (!tmp_path) {
+ op_ret = -ENOMEM;
+ goto out;
+ }
+
+ parent_path = dirname (tmp_path);
+
+ op_ret = posix_lstat_with_gfid (this, parent_path, &parent_stbuf);
+ if (op_ret == -1) {
+ op_ret = -errno;
+ gf_log_callingfn (this->name, GF_LOG_ERROR,
+ "lstat on parent directory (%s) failed: %s",
+ parent_path, strerror (errno));
+ goto out;
+ }
+
+ if (parent_stbuf.ia_prot.sgid) {
+ /*
+ * Entries created inside a setgid directory
+ * should inherit the gid from the parent
+ */
+
+ *gid = parent_stbuf.ia_gid;
+ }
+out:
+
+ if (tmp_path)
+ GF_FREE (tmp_path);
+
+ return op_ret;
+}
+
+
+int
+posix_gfid_set (xlator_t *this, const char *path, dict_t *xattr_req)
+{
+ void *uuid_req = NULL;
+ uuid_t uuid_curr;
+ int ret = 0;
+ struct stat stat = {0, };
+
+ if (!xattr_req)
+ goto out;
+
+ if (sys_lstat (path, &stat) != 0)
+ goto out;
+
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
+ if (ret == 16) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_ptr (xattr_req, "gfid-req", &uuid_req);
+ if (ret) {
+ gf_log_callingfn (this->name, GF_LOG_DEBUG,
+ "failed to get the gfid from dict");
+ goto out;
+ }
+
+ ret = sys_lsetxattr (path, GFID_XATTR_KEY, uuid_req, 16, XATTR_CREATE);
+
+out:
+ return ret;
+}
+
+
+int
+posix_set_file_contents (xlator_t *this, char *real_path,
+ data_pair_t *trav, int flags)
+{
+ char * key = NULL;
+ char real_filepath[ZR_PATH_MAX] = {0,};
+ int32_t file_fd = -1;
+ int op_ret = 0;
+ int ret = -1;
+
+ key = &(trav->key[15]);
+ sprintf (real_filepath, "%s/%s", real_path, key);
+
+ if (flags & XATTR_REPLACE) {
+ /* if file exists, replace it
+ * else, error out */
+ file_fd = open (real_filepath, O_TRUNC|O_WRONLY);
+
+ if (file_fd == -1) {
+ goto create;
+ }
+
+ if (trav->value->len) {
+ ret = write (file_fd, trav->value->data,
+ trav->value->len);
+ if (ret == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "write failed while doing setxattr "
+ "for key %s on path %s: %s",
+ key, real_filepath, strerror (errno));
+ goto out;
+ }
+
+ ret = close (file_fd);
+ if (ret == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "close failed on %s: %s",
+ real_filepath, strerror (errno));
+ goto out;
+ }
+ }
+
+ create: /* we know file doesn't exist, create it */
+
+ file_fd = open (real_filepath, O_CREAT|O_WRONLY, 0644);
+
+ if (file_fd == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to open file %s with O_CREAT: %s",
+ key, strerror (errno));
+ goto out;
+ }
+
+ ret = write (file_fd, trav->value->data, trav->value->len);
+ if (ret == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "write failed on %s while setxattr with "
+ "key %s: %s",
+ real_filepath, key, strerror (errno));
+ goto out;
+ }
+
+ ret = close (file_fd);
+ if (ret == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "close failed on %s while setxattr with "
+ "key %s: %s",
+ real_filepath, key, strerror (errno));
+ goto out;
+ }
+ }
+
+out:
+ return op_ret;
+}
+
+
+int
+posix_get_file_contents (xlator_t *this, char *real_path,
+ const char *name, char **contents)
+{
+ char real_filepath[ZR_PATH_MAX] = {0,};
+ char * key = NULL;
+ int32_t file_fd = -1;
+ struct iatt stbuf = {0,};
+ int op_ret = 0;
+ int ret = -1;
+
+ key = (char *) &(name[15]);
+ sprintf (real_filepath, "%s/%s", real_path, key);
+
+ op_ret = posix_lstat_with_gfid (this, real_filepath, &stbuf);
+ if (op_ret == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR, "lstat failed on %s: %s",
+ real_filepath, strerror (errno));
+ goto out;
+ }
+
+ file_fd = open (real_filepath, O_RDONLY);
+
+ if (file_fd == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR, "open failed on %s: %s",
+ real_filepath, strerror (errno));
+ goto out;
+ }
+
+ *contents = GF_CALLOC (stbuf.ia_size + 1, sizeof(char),
+ gf_posix_mt_char);
+ if (! *contents) {
+ op_ret = -errno;
+ goto out;
+ }
+
+ ret = read (file_fd, *contents, stbuf.ia_size);
+ if (ret <= 0) {
+ op_ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "read on %s failed: %s",
+ real_filepath, strerror (errno));
+ goto out;
+ }
+
+ *contents[stbuf.ia_size] = '\0';
+
+ op_ret = close (file_fd);
+ file_fd = -1;
+ if (op_ret == -1) {
+ op_ret = -errno;
+ gf_log (this->name, GF_LOG_ERROR, "close on %s failed: %s",
+ real_filepath, strerror (errno));
+ goto out;
+ }
+
+out:
+ if (op_ret < 0) {
+ if (*contents)
+ GF_FREE (*contents);
+ if (file_fd != -1)
+ close (file_fd);
+ }
+
+ return op_ret;
+}
+
+static int gf_xattr_enotsup_log;
+
+int
+posix_handle_pair (xlator_t *this, char *real_path,
+ data_pair_t *trav, int flags)
+{
+ int sys_ret = -1;
+ int ret = 0;
+
+ if (ZR_FILE_CONTENT_REQUEST(trav->key)) {
+ ret = posix_set_file_contents (this, real_path, trav, flags);
+ } else {
+ sys_ret = sys_lsetxattr (real_path, trav->key,
+ trav->value->data,
+ trav->value->len, flags);
+
+ if (sys_ret < 0) {
+ if (errno == ENOTSUP) {
+ GF_LOG_OCCASIONALLY(gf_xattr_enotsup_log,
+ this->name,GF_LOG_WARNING,
+ "Extended attributes not "
+ "supported");
+ } else if (errno == ENOENT) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "setxattr on %s failed: %s", real_path,
+ strerror (errno));
+ } else {
+
+#ifdef GF_DARWIN_HOST_OS
+ gf_log (this->name,
+ ((errno == EINVAL) ?
+ GF_LOG_DEBUG : GF_LOG_ERROR),
+ "%s: key:%s error:%s",
+ real_path, trav->key,
+ strerror (errno));
+#else /* ! DARWIN */
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: key:%s error:%s",
+ real_path, trav->key,
+ strerror (errno));
+#endif /* DARWIN */
+ }
+
+ ret = -errno;
+ goto out;
+ }
+ }
+out:
+ return ret;
+}
+
+int
+posix_fhandle_pair (xlator_t *this, int fd,
+ data_pair_t *trav, int flags)
+{
+ int sys_ret = -1;
+ int ret = 0;
+
+ sys_ret = sys_fsetxattr (fd, trav->key, trav->value->data,
+ trav->value->len, flags);
+
+ if (sys_ret < 0) {
+ if (errno == ENOTSUP) {
+ GF_LOG_OCCASIONALLY(gf_xattr_enotsup_log,
+ this->name,GF_LOG_WARNING,
+ "Extended attributes not "
+ "supported");
+ } else if (errno == ENOENT) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "fsetxattr on fd=%d failed: %s", fd,
+ strerror (errno));
+ } else {
+
+#ifdef GF_DARWIN_HOST_OS
+ gf_log (this->name,
+ ((errno == EINVAL) ?
+ GF_LOG_DEBUG : GF_LOG_ERROR),
+ "fd=%d: key:%s error:%s",
+ fd, trav->key,
+ strerror (errno));
+#else /* ! DARWIN */
+ gf_log (this->name, GF_LOG_ERROR,
+ "fd=%d: key:%s error:%s",
+ fd, trav->key,
+ strerror (errno));
+#endif /* DARWIN */
+ }
+
+ ret = -errno;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+static int
+janitor_walker (const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf)
+{
+ switch (sb->st_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFBLK:
+ case S_IFLNK:
+ case S_IFCHR:
+ case S_IFIFO:
+ case S_IFSOCK:
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "unlinking %s", fpath);
+ unlink (fpath);
+ break;
+
+ case S_IFDIR:
+ if (ftwbuf->level) { /* don't remove top level dir */
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "removing directory %s", fpath);
+
+ rmdir (fpath);
+ }
+ break;
+ }
+
+ return 0; /* 0 = FTW_CONTINUE */
+}
+
+
+static struct posix_fd *
+janitor_get_next_fd (xlator_t *this)
+{
+ struct posix_private *priv = NULL;
+ struct posix_fd *pfd = NULL;
+
+ struct timespec timeout;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->janitor_lock);
+ {
+ if (list_empty (&priv->janitor_fds)) {
+ time (&timeout.tv_sec);
+ timeout.tv_sec += priv->janitor_sleep_duration;
+ timeout.tv_nsec = 0;
+
+ pthread_cond_timedwait (&priv->janitor_cond,
+ &priv->janitor_lock,
+ &timeout);
+ goto unlock;
+ }
+
+ pfd = list_entry (priv->janitor_fds.next, struct posix_fd,
+ list);
+
+ list_del (priv->janitor_fds.next);
+ }
+unlock:
+ pthread_mutex_unlock (&priv->janitor_lock);
+
+ return pfd;
+}
+
+
+static void *
+posix_janitor_thread_proc (void *data)
+{
+ xlator_t * this = NULL;
+ struct posix_private *priv = NULL;
+ struct posix_fd *pfd;
+
+ time_t now;
+
+ this = data;
+ priv = this->private;
+
+ THIS = this;
+
+ while (1) {
+ time (&now);
+ if ((now - priv->last_landfill_check) > priv->janitor_sleep_duration) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "janitor cleaning out /" GF_REPLICATE_TRASH_DIR);
+
+ nftw (priv->trash_path,
+ janitor_walker,
+ 32,
+ FTW_DEPTH | FTW_PHYS);
+
+ priv->last_landfill_check = now;
+ }
+
+ pfd = janitor_get_next_fd (this);
+ if (pfd) {
+ if (pfd->dir == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "janitor: closing file fd=%d", pfd->fd);
+ close (pfd->fd);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "janitor: closing dir fd=%p", pfd->dir);
+ closedir (pfd->dir);
+ }
+
+ if (pfd->path)
+ GF_FREE (pfd->path);
+
+ GF_FREE (pfd);
+ }
+ }
+
+ return NULL;
+}
+
+
+void
+posix_spawn_janitor_thread (xlator_t *this)
+{
+ struct posix_private *priv = NULL;
+ int ret = 0;
+
+ priv = this->private;
+
+ LOCK (&priv->lock);
+ {
+ if (!priv->janitor_present) {
+ ret = pthread_create (&priv->janitor, NULL,
+ posix_janitor_thread_proc, this);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "spawning janitor thread failed: %s",
+ strerror (errno));
+ goto unlock;
+ }
+
+ priv->janitor_present = _gf_true;
+ }
+ }
+unlock:
+ UNLOCK (&priv->lock);
+}
+
+static int
+is_fresh_file (struct stat *stat)
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+
+ if ((stat->st_ctime >= (tv.tv_sec - 1))
+ && (stat->st_ctime <= tv.tv_sec))
+ return 1;
+
+ return 0;
+}
+
+
+int
+posix_gfid_heal (xlator_t *this, const char *path, dict_t *xattr_req)
+{
+ /* The purpose of this function is to prevent a race
+ where an inode creation FOP (like mkdir/mknod/create etc)
+ races with lookup in the following way:
+
+ {create thread} | {lookup thread}
+ |
+ t0
+ mkdir ("name") |
+ t1
+ | posix_gfid_set ("name", 2);
+ t2
+ posix_gfid_set ("name", 1); |
+ t3
+ lstat ("name"); | lstat ("name");
+
+ In the above case mkdir FOP would have resulted with GFID 2 while
+ it should have been GFID 1. It matters in the case where GFID would
+ have gotten set to 1 on other subvolumes of replciate/distribute
+
+ The "solution" here is that, if we detect lookup is attempting to
+ set a GFID on a file which is created very recently, but does not
+ yet have a GFID (i.e, between t1 and t2), then "fake" it as though
+ posix_gfid_heal was called at t0 instead.
+ */
+
+ uuid_t uuid_curr;
+ int ret = 0;
+ struct stat stat = {0, };
+
+ if (!xattr_req)
+ goto out;
+
+ if (sys_lstat (path, &stat) != 0)
+ goto out;
+
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
+ if (ret != 16) {
+ if (is_fresh_file (&stat)) {
+ ret = -1;
+ errno = ENOENT;
+ goto out;
+ }
+ }
+
+ ret = posix_gfid_set (this, path, xattr_req);
+out:
+ return ret;
+}
+
+
+int
+posix_acl_xattr_set (xlator_t *this, const char *path, dict_t *xattr_req)
+{
+ int ret = 0;
+ data_t *data = NULL;
+ struct stat stat = {0, };
+
+ if (!xattr_req)
+ goto out;
+
+ if (sys_lstat (path, &stat) != 0)
+ goto out;
+
+ data = dict_get (xattr_req, "system.posix_acl_access");
+ if (data) {
+ ret = sys_lsetxattr (path, "system.posix_acl_access",
+ data->data, data->len, 0);
+ if (ret != 0)
+ goto out;
+ }
+
+ data = dict_get (xattr_req, "system.posix_acl_default");
+ if (data) {
+ ret = sys_lsetxattr (path, "system.posix_acl_default",
+ data->data, data->len, 0);
+ if (ret != 0)
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 5240659ab..eb78ea739 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -80,14 +80,6 @@
#endif
-typedef struct {
- xlator_t *this;
- const char *real_path;
- dict_t *xattr;
- struct iatt *stbuf;
- loc_t *loc;
-} posix_xattr_filler_t;
-
int
posix_forget (xlator_t *this, inode_t *inode)
{
@@ -98,434 +90,7 @@ posix_forget (xlator_t *this, inode_t *inode)
return 0;
}
-static void
-_posix_xattr_get_set (dict_t *xattr_req,
- char *key,
- data_t *data,
- void *xattrargs)
-{
- posix_xattr_filler_t *filler = xattrargs;
- char *value = NULL;
- ssize_t xattr_size = -1;
- int ret = -1;
- char *databuf = NULL;
- int _fd = -1;
- loc_t *loc = NULL;
- ssize_t req_size = 0;
-
-
- if (!strcmp (key, "gfid-req"))
- return;
- /* should size be put into the data_t ? */
- if (!strcmp (key, GF_CONTENT_KEY)
- && IA_ISREG (filler->stbuf->ia_type)) {
-
- /* file content request */
- req_size = data_to_uint64 (data);
- if (req_size >= filler->stbuf->ia_size) {
- _fd = open (filler->real_path, O_RDONLY);
- if (_fd == -1) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "Opening file %s failed: %s",
- filler->real_path, strerror (errno));
- goto err;
- }
-
- databuf = GF_CALLOC (1, filler->stbuf->ia_size,
- gf_posix_mt_char);
- if (!databuf) {
- goto err;
- }
-
- ret = read (_fd, databuf, filler->stbuf->ia_size);
- if (ret == -1) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "Read on file %s failed: %s",
- filler->real_path, strerror (errno));
- goto err;
- }
-
- ret = close (_fd);
- _fd = -1;
- if (ret == -1) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "Close on file %s failed: %s",
- filler->real_path, strerror (errno));
- goto err;
- }
-
- ret = dict_set_bin (filler->xattr, key,
- databuf, filler->stbuf->ia_size);
- if (ret < 0) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "failed to set dict value. key: %s, path: %s",
- key, filler->real_path);
- goto err;
- }
-
- /* To avoid double free in cleanup below */
- databuf = NULL;
- err:
- if (_fd != -1)
- close (_fd);
- if (databuf)
- GF_FREE (databuf);
- }
- } else if (!strcmp (key, GLUSTERFS_OPEN_FD_COUNT)) {
- loc = filler->loc;
- if (!list_empty (&loc->inode->fd_list)) {
- ret = dict_set_uint32 (filler->xattr, key, 1);
- if (ret < 0)
- gf_log (filler->this->name, GF_LOG_WARNING,
- "Failed to set dictionary value for %s",
- key);
- } else {
- ret = dict_set_uint32 (filler->xattr, key, 0);
- if (ret < 0)
- gf_log (filler->this->name, GF_LOG_WARNING,
- "Failed to set dictionary value for %s",
- key);
- }
- } else {
- xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0);
-
- if (xattr_size > 0) {
- value = GF_CALLOC (1, xattr_size + 1,
- gf_posix_mt_char);
- if (!value)
- return;
-
- sys_lgetxattr (filler->real_path, key, value,
- xattr_size);
-
- value[xattr_size] = '\0';
- ret = dict_set_bin (filler->xattr, key,
- value, xattr_size);
- if (ret < 0)
- gf_log (filler->this->name, GF_LOG_DEBUG,
- "dict set failed. path: %s, key: %s",
- filler->real_path, key);
- }
- }
-}
-
-
-int
-posix_fill_gfid_path (xlator_t *this, const char *path, struct iatt *iatt)
-{
- int ret = 0;
-
- if (!iatt)
- return 0;
-
- ret = sys_lgetxattr (path, GFID_XATTR_KEY, iatt->ia_gfid, 16);
- /* Return value of getxattr */
- if (ret == 16)
- ret = 0;
-
- return ret;
-}
-
-
-int
-posix_fill_gfid_fd (xlator_t *this, int fd, struct iatt *iatt)
-{
- int ret = 0;
-
- if (!iatt)
- return 0;
-
- ret = sys_fgetxattr (fd, GFID_XATTR_KEY, iatt->ia_gfid, 16);
- /* Return value of getxattr */
- if (ret == 16)
- ret = 0;
-
- return ret;
-}
-
-void
-posix_fill_ino_from_gfid (xlator_t *this, struct iatt *buf)
-{
- uint64_t temp_ino = 0;
- int j = 0;
- int i = 0;
-
- /* consider least significant 8 bytes of value out of gfid */
- for (i = 15; i > (15 - 8); i--) {
- temp_ino += buf->ia_gfid[i] << j;
- j += 8;
- }
-
- buf->ia_ino = temp_ino;
-}
-
-int
-posix_lstat_with_gfid (xlator_t *this, const char *path, struct iatt *stbuf_p)
-{
- struct posix_private *priv = NULL;
- int ret = 0;
- struct stat lstatbuf = {0, };
- struct iatt stbuf = {0, };
-
- priv = this->private;
-
- ret = lstat (path, &lstatbuf);
- if (ret == -1)
- goto out;
-
- iatt_from_stat (&stbuf, &lstatbuf);
-
- ret = posix_fill_gfid_path (this, path, &stbuf);
- if (ret)
- gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
-
- posix_fill_ino_from_gfid (this, &stbuf);
-
- if (stbuf_p)
- *stbuf_p = stbuf;
-out:
- return ret;
-}
-
-
-int
-posix_fstat_with_gfid (xlator_t *this, int fd, struct iatt *stbuf_p)
-{
- struct posix_private *priv = NULL;
- int ret = 0;
- struct stat fstatbuf = {0, };
- struct iatt stbuf = {0, };
-
- priv = this->private;
-
- ret = fstat (fd, &fstatbuf);
- if (ret == -1)
- goto out;
-
- iatt_from_stat (&stbuf, &fstatbuf);
-
- ret = posix_fill_gfid_fd (this, fd, &stbuf);
- if (ret)
- gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
-
- posix_fill_ino_from_gfid (this, &stbuf);
-
- if (stbuf_p)
- *stbuf_p = stbuf;
-
-out:
- return ret;
-}
-
-
-dict_t *
-posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc,
- dict_t *xattr_req, struct iatt *buf)
-{
- dict_t *xattr = NULL;
- posix_xattr_filler_t filler = {0, };
-
- xattr = get_new_dict();
- if (!xattr) {
- goto out;
- }
-
- filler.this = this;
- filler.real_path = real_path;
- filler.xattr = xattr;
- filler.stbuf = buf;
- filler.loc = loc;
-
- dict_foreach (xattr_req, _posix_xattr_get_set, &filler);
-out:
- return xattr;
-}
-
-
-/*
- * If the parent directory of {real_path} has the setgid bit set,
- * then set {gid} to the gid of the parent. Otherwise,
- * leave {gid} unchanged.
- */
-
-int
-setgid_override (xlator_t *this, char *real_path, gid_t *gid)
-{
- char * tmp_path = NULL;
- char * parent_path = NULL;
- struct iatt parent_stbuf;
-
- int op_ret = 0;
-
- tmp_path = gf_strdup (real_path);
- if (!tmp_path) {
- op_ret = -ENOMEM;
- goto out;
- }
-
- parent_path = dirname (tmp_path);
-
- op_ret = posix_lstat_with_gfid (this, parent_path, &parent_stbuf);
- if (op_ret == -1) {
- op_ret = -errno;
- gf_log_callingfn (this->name, GF_LOG_ERROR,
- "lstat on parent directory (%s) failed: %s",
- parent_path, strerror (errno));
- goto out;
- }
-
- if (parent_stbuf.ia_prot.sgid) {
- /*
- * Entries created inside a setgid directory
- * should inherit the gid from the parent
- */
-
- *gid = parent_stbuf.ia_gid;
- }
-out:
-
- if (tmp_path)
- GF_FREE (tmp_path);
-
- return op_ret;
-}
-
-
-int
-posix_gfid_set (xlator_t *this, const char *path, dict_t *xattr_req)
-{
- void *uuid_req = NULL;
- uuid_t uuid_curr;
- int ret = 0;
- struct stat stat = {0, };
-
- if (!xattr_req)
- goto out;
-
- if (sys_lstat (path, &stat) != 0)
- goto out;
-
- ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
- if (ret == 16) {
- ret = 0;
- goto out;
- }
-
- ret = dict_get_ptr (xattr_req, "gfid-req", &uuid_req);
- if (ret) {
- gf_log_callingfn (this->name, GF_LOG_DEBUG,
- "failed to get the gfid from dict");
- goto out;
- }
-
- ret = sys_lsetxattr (path, GFID_XATTR_KEY, uuid_req, 16, XATTR_CREATE);
-
-out:
- return ret;
-}
-
-
-static int
-is_fresh_file (struct stat *stat)
-{
- struct timeval tv;
-
- gettimeofday (&tv, NULL);
-
- if ((stat->st_ctime >= (tv.tv_sec - 1))
- && (stat->st_ctime <= tv.tv_sec))
- return 1;
-
- return 0;
-}
-
-
-int
-posix_gfid_heal (xlator_t *this, const char *path, dict_t *xattr_req)
-{
- /* The purpose of this function is to prevent a race
- where an inode creation FOP (like mkdir/mknod/create etc)
- races with lookup in the following way:
-
- {create thread} | {lookup thread}
- |
- t0
- mkdir ("name") |
- t1
- | posix_gfid_set ("name", 2);
- t2
- posix_gfid_set ("name", 1); |
- t3
- lstat ("name"); | lstat ("name");
-
- In the above case mkdir FOP would have resulted with GFID 2 while
- it should have been GFID 1. It matters in the case where GFID would
- have gotten set to 1 on other subvolumes of replciate/distribute
-
- The "solution" here is that, if we detect lookup is attempting to
- set a GFID on a file which is created very recently, but does not
- yet have a GFID (i.e, between t1 and t2), then "fake" it as though
- posix_gfid_heal was called at t0 instead.
- */
-
- uuid_t uuid_curr;
- int ret = 0;
- struct stat stat = {0, };
-
- if (!xattr_req)
- goto out;
-
- if (sys_lstat (path, &stat) != 0)
- goto out;
-
- ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
- if (ret != 16) {
- if (is_fresh_file (&stat)) {
- ret = -1;
- errno = ENOENT;
- goto out;
- }
- }
-
- ret = posix_gfid_set (this, path, xattr_req);
-out:
- return ret;
-}
-
-
-int
-posix_acl_xattr_set (xlator_t *this, const char *path, dict_t *xattr_req)
-{
- int ret = 0;
- data_t *data = NULL;
- struct stat stat = {0, };
-
- if (!xattr_req)
- goto out;
-
- if (sys_lstat (path, &stat) != 0)
- goto out;
-
- data = dict_get (xattr_req, "system.posix_acl_access");
- if (data) {
- ret = sys_lsetxattr (path, "system.posix_acl_access",
- data->data, data->len, 0);
- if (ret != 0)
- goto out;
- }
-
- data = dict_get (xattr_req, "system.posix_acl_default");
- if (data) {
- ret = sys_lsetxattr (path, "system.posix_acl_default",
- data->data, data->len, 0);
- if (ret != 0)
- goto out;
- }
-
-out:
- return ret;
-}
-
+/* Regular fops */
int32_t
posix_lookup (call_frame_t *frame, xlator_t *this,
@@ -1298,152 +863,6 @@ out:
return 0;
}
-
-static int
-janitor_walker (const char *fpath, const struct stat *sb,
- int typeflag, struct FTW *ftwbuf)
-{
- switch (sb->st_mode & S_IFMT) {
- case S_IFREG:
- case S_IFBLK:
- case S_IFLNK:
- case S_IFCHR:
- case S_IFIFO:
- case S_IFSOCK:
- gf_log (THIS->name, GF_LOG_TRACE,
- "unlinking %s", fpath);
- unlink (fpath);
- break;
-
- case S_IFDIR:
- if (ftwbuf->level) { /* don't remove top level dir */
- gf_log (THIS->name, GF_LOG_TRACE,
- "removing directory %s", fpath);
-
- rmdir (fpath);
- }
- break;
- }
-
- return 0; /* 0 = FTW_CONTINUE */
-}
-
-
-static struct posix_fd *
-janitor_get_next_fd (xlator_t *this)
-{
- struct posix_private *priv = NULL;
- struct posix_fd *pfd = NULL;
-
- struct timespec timeout;
-
- priv = this->private;
-
- pthread_mutex_lock (&priv->janitor_lock);
- {
- if (list_empty (&priv->janitor_fds)) {
- time (&timeout.tv_sec);
- timeout.tv_sec += priv->janitor_sleep_duration;
- timeout.tv_nsec = 0;
-
- pthread_cond_timedwait (&priv->janitor_cond,
- &priv->janitor_lock,
- &timeout);
- goto unlock;
- }
-
- pfd = list_entry (priv->janitor_fds.next, struct posix_fd,
- list);
-
- list_del (priv->janitor_fds.next);
- }
-unlock:
- pthread_mutex_unlock (&priv->janitor_lock);
-
- return pfd;
-}
-
-
-static void *
-posix_janitor_thread_proc (void *data)
-{
- xlator_t * this = NULL;
- struct posix_private *priv = NULL;
- struct posix_fd *pfd;
-
- time_t now;
-
- this = data;
- priv = this->private;
-
- THIS = this;
-
- while (1) {
- time (&now);
- if ((now - priv->last_landfill_check) > priv->janitor_sleep_duration) {
- gf_log (this->name, GF_LOG_TRACE,
- "janitor cleaning out /" GF_REPLICATE_TRASH_DIR);
-
- nftw (priv->trash_path,
- janitor_walker,
- 32,
- FTW_DEPTH | FTW_PHYS);
-
- priv->last_landfill_check = now;
- }
-
- pfd = janitor_get_next_fd (this);
- if (pfd) {
- if (pfd->dir == NULL) {
- gf_log (this->name, GF_LOG_TRACE,
- "janitor: closing file fd=%d", pfd->fd);
- close (pfd->fd);
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "janitor: closing dir fd=%p", pfd->dir);
- closedir (pfd->dir);
- }
-
- if (pfd->path)
- GF_FREE (pfd->path);
-
- GF_FREE (pfd);
- }
- }
-
- return NULL;
-}
-
-
-static void
-posix_spawn_janitor_thread (xlator_t *this)
-{
- struct posix_private *priv = NULL;
- int ret = 0;
-
- priv = this->private;
-
- LOCK (&priv->lock);
- {
- if (!priv->janitor_present) {
- ret = pthread_create (&priv->janitor, NULL,
- posix_janitor_thread_proc, this);
-
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "spawning janitor thread failed: %s",
- strerror (errno));
- goto unlock;
- }
-
- priv->janitor_present = _gf_true;
- }
- }
-unlock:
- UNLOCK (&priv->lock);
-}
-
-
int
posix_mkdir (call_frame_t *frame, xlator_t *this,
loc_t *loc, mode_t mode, dict_t *params)
@@ -2976,136 +2395,6 @@ out:
static int gf_posix_xattr_enotsup_log;
-int
-set_file_contents (xlator_t *this, char *real_path,
- data_pair_t *trav, int flags)
-{
- char * key = NULL;
- char real_filepath[ZR_PATH_MAX] = {0,};
- int32_t file_fd = -1;
- int op_ret = 0;
- int ret = -1;
-
- key = &(trav->key[15]);
- sprintf (real_filepath, "%s/%s", real_path, key);
-
- if (flags & XATTR_REPLACE) {
- /* if file exists, replace it
- * else, error out */
- file_fd = open (real_filepath, O_TRUNC|O_WRONLY);
-
- if (file_fd == -1) {
- goto create;
- }
-
- if (trav->value->len) {
- ret = write (file_fd, trav->value->data,
- trav->value->len);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "write failed while doing setxattr "
- "for key %s on path %s: %s",
- key, real_filepath, strerror (errno));
- goto out;
- }
-
- ret = close (file_fd);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "close failed on %s: %s",
- real_filepath, strerror (errno));
- goto out;
- }
- }
-
- create: /* we know file doesn't exist, create it */
-
- file_fd = open (real_filepath, O_CREAT|O_WRONLY, 0644);
-
- if (file_fd == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to open file %s with O_CREAT: %s",
- key, strerror (errno));
- goto out;
- }
-
- ret = write (file_fd, trav->value->data, trav->value->len);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "write failed on %s while setxattr with "
- "key %s: %s",
- real_filepath, key, strerror (errno));
- goto out;
- }
-
- ret = close (file_fd);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "close failed on %s while setxattr with "
- "key %s: %s",
- real_filepath, key, strerror (errno));
- goto out;
- }
- }
-
-out:
- return op_ret;
-}
-
-int
-handle_pair (xlator_t *this, char *real_path,
- data_pair_t *trav, int flags)
-{
- int sys_ret = -1;
- int ret = 0;
-
- if (ZR_FILE_CONTENT_REQUEST(trav->key)) {
- ret = set_file_contents (this, real_path, trav, flags);
- } else {
- sys_ret = sys_lsetxattr (real_path, trav->key,
- trav->value->data,
- trav->value->len, flags);
-
- if (sys_ret < 0) {
- if (errno == ENOTSUP) {
- GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log,
- this->name,GF_LOG_WARNING,
- "Extended attributes not "
- "supported");
- } else if (errno == ENOENT) {
- gf_log (this->name, GF_LOG_ERROR,
- "setxattr on %s failed: %s", real_path,
- strerror (errno));
- } else {
-
-#ifdef GF_DARWIN_HOST_OS
- gf_log (this->name,
- ((errno == EINVAL) ?
- GF_LOG_DEBUG : GF_LOG_ERROR),
- "%s: key:%s error:%s",
- real_path, trav->key,
- strerror (errno));
-#else /* ! DARWIN */
- gf_log (this->name, GF_LOG_ERROR,
- "%s: key:%s error:%s",
- real_path, trav->key,
- strerror (errno));
-#endif /* DARWIN */
- }
-
- ret = -errno;
- goto out;
- }
- }
-out:
- return ret;
-}
-
int32_t
posix_setxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *dict, int flags)
@@ -3131,7 +2420,7 @@ posix_setxattr (call_frame_t *frame, xlator_t *this,
trav = dict->members_list;
while (trav) {
- ret = handle_pair (this, real_path, trav, flags);
+ ret = posix_handle_pair (this, real_path, trav, flags);
if (ret < 0) {
op_errno = -ret;
goto out;
@@ -3149,74 +2438,6 @@ out:
return 0;
}
-int
-get_file_contents (xlator_t *this, char *real_path,
- const char *name, char **contents)
-{
- char real_filepath[ZR_PATH_MAX] = {0,};
- char * key = NULL;
- int32_t file_fd = -1;
- struct iatt stbuf = {0,};
- int op_ret = 0;
- int ret = -1;
-
- key = (char *) &(name[15]);
- sprintf (real_filepath, "%s/%s", real_path, key);
-
- op_ret = posix_lstat_with_gfid (this, real_filepath, &stbuf);
- if (op_ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR, "lstat failed on %s: %s",
- real_filepath, strerror (errno));
- goto out;
- }
-
- file_fd = open (real_filepath, O_RDONLY);
-
- if (file_fd == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR, "open failed on %s: %s",
- real_filepath, strerror (errno));
- goto out;
- }
-
- *contents = GF_CALLOC (stbuf.ia_size + 1, sizeof(char),
- gf_posix_mt_char);
- if (! *contents) {
- op_ret = -errno;
- goto out;
- }
-
- ret = read (file_fd, *contents, stbuf.ia_size);
- if (ret <= 0) {
- op_ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "read on %s failed: %s",
- real_filepath, strerror (errno));
- goto out;
- }
-
- *contents[stbuf.ia_size] = '\0';
-
- op_ret = close (file_fd);
- file_fd = -1;
- if (op_ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR, "close on %s failed: %s",
- real_filepath, strerror (errno));
- goto out;
- }
-
-out:
- if (op_ret < 0) {
- if (*contents)
- GF_FREE (*contents);
- if (file_fd != -1)
- close (file_fd);
- }
-
- return op_ret;
-}
-
/**
* posix_getxattr - this function returns a dictionary with all the
* key:value pair present as xattr. used for
@@ -3254,8 +2475,8 @@ posix_getxattr (call_frame_t *frame, xlator_t *this,
if (loc->inode && IA_ISDIR(loc->inode->ia_type) && name &&
ZR_FILE_CONTENT_REQUEST(name)) {
- ret = get_file_contents (this, real_path, name,
- &file_contents);
+ ret = posix_get_file_contents (this, real_path, name,
+ &file_contents);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_ERROR,
@@ -3510,52 +2731,6 @@ out:
}
-int
-fhandle_pair (xlator_t *this, int fd,
- data_pair_t *trav, int flags)
-{
- int sys_ret = -1;
- int ret = 0;
-
- sys_ret = sys_fsetxattr (fd, trav->key, trav->value->data,
- trav->value->len, flags);
-
- if (sys_ret < 0) {
- if (errno == ENOTSUP) {
- GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log,
- this->name,GF_LOG_WARNING,
- "Extended attributes not "
- "supported");
- } else if (errno == ENOENT) {
- gf_log (this->name, GF_LOG_ERROR,
- "fsetxattr on fd=%d failed: %s", fd,
- strerror (errno));
- } else {
-
-#ifdef GF_DARWIN_HOST_OS
- gf_log (this->name,
- ((errno == EINVAL) ?
- GF_LOG_DEBUG : GF_LOG_ERROR),
- "fd=%d: key:%s error:%s",
- fd, trav->key,
- strerror (errno));
-#else /* ! DARWIN */
- gf_log (this->name, GF_LOG_ERROR,
- "fd=%d: key:%s error:%s",
- fd, trav->key,
- strerror (errno));
-#endif /* DARWIN */
- }
-
- ret = -errno;
- goto out;
- }
-
-out:
- return ret;
-}
-
-
int32_t
posix_fsetxattr (call_frame_t *frame, xlator_t *this,
fd_t *fd, dict_t *dict, int flags)
@@ -3591,7 +2766,7 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this,
trav = dict->members_list;
while (trav) {
- ret = fhandle_pair (this, _fd, trav, flags);
+ ret = posix_fhandle_pair (this, _fd, trav, flags);
if (ret < 0) {
op_errno = -ret;
goto out;
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index d7b56961a..f57bc0d7b 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -126,4 +126,24 @@ struct posix_private {
strcpy (&var[POSIX_BASE_PATH_LEN(this)], path); \
} while (0)
+
+/* Helper functions */
+int setgid_override (xlator_t *this, char *real_path, gid_t *gid);
+int posix_gfid_set (xlator_t *this, const char *path, dict_t *xattr_req);
+int posix_fstat_with_gfid (xlator_t *this, int fd, struct iatt *stbuf_p);
+int posix_lstat_with_gfid (xlator_t *this, const char *path, struct iatt *buf);
+dict_t *posix_lookup_xattr_fill (xlator_t *this, const char *path,
+ loc_t *loc, dict_t *xattr, struct iatt *buf);
+int posix_handle_pair (xlator_t *this, char *real_path,
+ data_pair_t *trav, int flags);
+int posix_fhandle_pair (xlator_t *this, int fd, data_pair_t *trav, int flags);
+void posix_spawn_janitor_thread (xlator_t *this);
+int posix_get_file_contents (xlator_t *this, char *path,
+ const char *name, char **contents);
+int posix_set_file_contents (xlator_t *this, char *path,
+ data_pair_t *trav, int flags);
+int posix_acl_xattr_set (xlator_t *this, const char *path, dict_t *xattr_req);
+int posix_gfid_heal (xlator_t *this, const char *path, dict_t *xattr_req);
+
+
#endif /* _POSIX_H */