summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src/afr.c
diff options
context:
space:
mode:
authorVikas Gorur <vikas@gluster.com>2009-04-07 06:55:43 -0700
committerAnand V. Avati <avati@amp.gluster.com>2009-04-07 23:19:08 +0530
commit5634986f594fe75d0cd2e69cadf002a2c701f366 (patch)
treeded4a1c4e4eba480a5abd30f133874e5a0f0c410 /xlators/cluster/afr/src/afr.c
parentd46684117a02359886e096d1bcc9f590b54144a6 (diff)
Fix in changelog logic.
If a writev fails, remember it by marking it in the fd context. Signed-off-by: Anand V. Avati <avati@amp.gluster.com>
Diffstat (limited to 'xlators/cluster/afr/src/afr.c')
-rw-r--r--xlators/cluster/afr/src/afr.c105
1 files changed, 103 insertions, 2 deletions
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c
index 76e28cc4c52..54a1d71af8f 100644
--- a/xlators/cluster/afr/src/afr.c
+++ b/xlators/cluster/afr/src/afr.c
@@ -44,6 +44,8 @@
#include "compat.h"
#include "byte-order.h"
+#include "fd.h"
+
#include "afr-inode-read.h"
#include "afr-inode-write.h"
#include "afr-dir-read.h"
@@ -698,10 +700,70 @@ out:
/* {{{ open */
int
+afr_fd_ctx_set (xlator_t *this, fd_t *fd)
+{
+ afr_private_t * priv = NULL;
+
+ int op_ret = 0;
+ int ret = 0;
+
+ uint64_t ctx;
+ afr_fd_ctx_t * fd_ctx = NULL;
+
+ priv = this->private;
+
+ LOCK (&fd->lock);
+ {
+ ret = __fd_ctx_get (fd, this, &ctx);
+
+ if (ret == 0)
+ goto out;
+
+ fd_ctx = CALLOC (1, sizeof (afr_fd_ctx_t));
+ if (!fd_ctx) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory :(");
+
+ op_ret = -ENOMEM;
+ goto out;
+ }
+
+ fd_ctx->child_failed = CALLOC (sizeof (*fd_ctx->child_failed),
+ priv->child_count);
+
+ if (!fd_ctx->child_failed) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory :(");
+
+ op_ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
+ if (ret < 0) {
+ op_ret = ret;
+ }
+ }
+out:
+ UNLOCK (&fd->lock);
+
+ return ret;
+}
+
+
+int
afr_open_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct stat *buf)
{
afr_local_t * local = frame->local;
+ int ret = 0;
+
+ ret = afr_fd_ctx_set (this, local->fd);
+
+ if (ret < 0) {
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ }
AFR_STACK_UNWIND (frame, local->op_ret, local->op_errno,
local->fd);
@@ -717,6 +779,8 @@ afr_open_cbk (call_frame_t *frame, void *cookie,
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
+ int ret = 0;
+
int call_count = -1;
priv = this->private;
@@ -743,8 +807,15 @@ afr_open_cbk (call_frame_t *frame, void *cookie,
this, this->fops->ftruncate,
fd, 0);
} else {
- AFR_STACK_UNWIND (frame, local->op_ret,
- local->op_errno, local->fd);
+ ret = afr_fd_ctx_set (this, fd);
+
+ if (ret < 0) {
+ local->op_ret = -1;
+ local->op_errno = -ret;
+
+ AFR_STACK_UNWIND (frame, local->op_ret,
+ local->op_errno, local->fd);
+ }
}
}
@@ -955,6 +1026,34 @@ out:
/* }}} */
+
+int
+afr_release (xlator_t *this, fd_t *fd)
+{
+ uint64_t ctx;
+ afr_fd_ctx_t * fd_ctx;
+
+ int ret = 0;
+
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0)
+ goto out;
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ if (fd_ctx) {
+ if (fd_ctx->child_failed)
+ FREE (fd_ctx->child_failed);
+
+ FREE (fd_ctx);
+ }
+
+out:
+ return 0;
+}
+
+
/* {{{ fsync */
int
@@ -2376,8 +2475,10 @@ struct xlator_mops mops = {
struct xlator_cbks cbks = {
+ .release = afr_release,
};
+
struct volume_options options[] = {
{ .key = {"read-subvolume" },
.type = GF_OPTION_TYPE_XLATOR