summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Hernandez <xhernandez@datalab.es>2014-07-08 17:52:57 +0200
committerVijay Bellur <vbellur@redhat.com>2014-08-11 04:34:13 -0700
commit8935623e316b0e4448be4badd860b03a3763ea12 (patch)
tree609a4f18f1e2c8d2955a941e8ad14a66c75ac3dd
parent9fa27cbfdd93b24d8e25c28dc673df4ff499736c (diff)
cluster/ec: Fix incorrect management of NFS requests
Some operations, specially those comming from NFS, do not use a regular fd and use an anonymous fd (i.e. a previous open call has not been sent). Any context information created during open or create will not be present on these fd's, so we simply return NULL for contexts of those fd. Also it seems that NFS can send write requests with a very big buffer (higher that the default value of 128 KB). Some changes have been made to correctly handle these large buffers. This is a backport of http://review.gluster.org/8367. Change-Id: I281476bd0d2cbaad231822248d6a616fcf5d4003 BUG: 1126734 Signed-off-by: Xavier Hernandez <xhernandez@datalab.es> Reviewed-on: http://review.gluster.org/8367 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> Reviewed-on: http://review.gluster.org/8416
-rw-r--r--tests/basic/ec/nfs.t18
-rw-r--r--xlators/cluster/ec/src/ec-helpers.c14
-rw-r--r--xlators/cluster/ec/src/ec-inode-read.c71
-rw-r--r--xlators/cluster/ec/src/ec-inode-write.c55
4 files changed, 69 insertions, 89 deletions
diff --git a/tests/basic/ec/nfs.t b/tests/basic/ec/nfs.t
new file mode 100644
index 00000000000..53ec30c92b0
--- /dev/null
+++ b/tests/basic/ec/nfs.t
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../nfs.rc
+
+cleanup
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 redundancy 2 $H0:$B0/${V0}{0..5}
+TEST $CLI volume start $V0
+
+EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available;
+TEST mount_nfs $H0:/$V0 $N0
+
+TEST dd if=/dev/zero of=$N0/test bs=1024k count=1k
+
+cleanup
diff --git a/xlators/cluster/ec/src/ec-helpers.c b/xlators/cluster/ec/src/ec-helpers.c
index cd0ac41ebe7..6eb836a1c62 100644
--- a/xlators/cluster/ec/src/ec-helpers.c
+++ b/xlators/cluster/ec/src/ec-helpers.c
@@ -531,6 +531,11 @@ ec_fd_t * __ec_fd_get(fd_t * fd, xlator_t * xl)
ec_fd_t * ctx = NULL;
uint64_t value = 0;
+ if (fd->anonymous)
+ {
+ return NULL;
+ }
+
if ((__fd_ctx_get(fd, xl, &value) != 0) || (value == 0))
{
ctx = GF_MALLOC(sizeof(*ctx), ec_mt_ec_fd_t);
@@ -559,11 +564,14 @@ ec_fd_t * ec_fd_get(fd_t * fd, xlator_t * xl)
{
ec_fd_t * ctx = NULL;
- LOCK(&fd->lock);
+ if (!fd->anonymous)
+ {
+ LOCK(&fd->lock);
- ctx = __ec_fd_get(fd, xl);
+ ctx = __ec_fd_get(fd, xl);
- UNLOCK(&fd->lock);
+ UNLOCK(&fd->lock);
+ }
return ctx;
}
diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c
index 46f904cf321..484c5e40189 100644
--- a/xlators/cluster/ec/src/ec-inode-read.c
+++ b/xlators/cluster/ec/src/ec-inode-read.c
@@ -973,11 +973,10 @@ out:
int32_t ec_readv_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
{
ec_cbk_data_t * ans = NULL;
- struct iobuf_pool * pool = NULL;
struct iobref * iobref = NULL;
struct iobuf * iobuf = NULL;
uint8_t * ptr = NULL, * buff = NULL;
- size_t fsize = 0, size = 0, max = 0, slice = 0;
+ size_t fsize = 0, size = 0, max = 0;
int32_t i = 0;
if (cbk->op_ret < 0)
@@ -989,7 +988,7 @@ int32_t ec_readv_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
if (cbk->op_ret > 0)
{
- struct iovec vector[cbk->int32 * cbk->count];
+ struct iovec vector[1];
uint8_t * blocks[cbk->count];
uint32_t values[cbk->count];
@@ -1001,50 +1000,33 @@ int32_t ec_readv_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
goto out;
}
buff = GF_ALIGN_BUF(ptr, EC_BUFFER_ALIGN_SIZE);
+ for (i = 0, ans = cbk; ans != NULL; i++, ans = ans->next)
+ {
+ values[i] = ans->idx;
+ blocks[i] = buff;
+ buff += ec_iov_copy_to(buff, ans->vector, ans->int32, 0, fsize);
+ }
iobref = iobref_new();
if (iobref == NULL)
{
goto out;
}
-
- for (i = 0, ans = cbk; ans != NULL; i++, ans = ans->next)
+ iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, size);
+ if (iobuf == NULL)
{
- values[i] = ans->idx;
- blocks[i] = buff;
- buff += ec_iov_copy_to(buff, ans->vector, ans->int32, 0, fsize);
+ goto out;
}
-
- pool = fop->xl->ctx->iobuf_pool;
- max = iobpool_default_pagesize(pool) / ec->stripe_size;
- max *= ec->fragment_size;
- i = 0;
- do
+ if (iobref_add(iobref, iobuf) != 0)
{
- iobuf = iobuf_get(pool);
- if (iobuf == NULL)
- {
- goto out;
- }
- if (iobref_add(iobref, iobuf) != 0)
- {
- goto out;
- }
-
- slice = fsize;
- if (slice > max)
- {
- slice = max;
- }
- fsize -= slice;
+ goto out;
+ }
- vector[i].iov_base = iobuf->ptr;
- vector[i].iov_len = ec_method_decode(slice, ec->fragments, values,
- blocks, iobuf->ptr);
- i++;
+ vector[0].iov_base = iobuf->ptr;
+ vector[0].iov_len = ec_method_decode(fsize, ec->fragments, values,
+ blocks, iobuf->ptr);
- iobuf_unref(iobuf);
- } while (fsize > 0);
+ iobuf_unref(iobuf);
GF_FREE(ptr);
ptr = NULL;
@@ -1063,27 +1045,20 @@ int32_t ec_readv_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
max = fop->user_size;
}
size -= fop->head;
- while (size > max)
+ if (size > max)
{
- if (size - max >= vector[i - 1].iov_len)
- {
- size -= vector[--i].iov_len;
- }
- else
- {
- vector[i - 1].iov_len -= size - max;
- size = max;
- }
+ vector[0].iov_len -= size - max;
+ size = max;
}
cbk->op_ret = size;
- cbk->int32 = i;
+ cbk->int32 = 1;
iobref_unref(cbk->buffers);
cbk->buffers = iobref;
GF_FREE(cbk->vector);
- cbk->vector = iov_dup(vector, i);
+ cbk->vector = iov_dup(vector, 1);
if (cbk->vector == NULL)
{
cbk->op_ret = -1;
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c
index c0694531151..06a2fef8d17 100644
--- a/xlators/cluster/ec/src/ec-inode-write.c
+++ b/xlators/cluster/ec/src/ec-inode-write.c
@@ -1932,18 +1932,10 @@ void ec_wind_writev(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
{
ec_trace("WIND", fop, "idx=%d", idx);
- struct iovec vector[fop->int32];
- struct iobuf_pool * pool = NULL;
+ struct iovec vector[1];
struct iobref * iobref = NULL;
struct iobuf * iobuf = NULL;
- uint8_t * ptr = NULL;
- ssize_t size = 0, slice = 0, pagesize = 0, maxsize = 0;
- int32_t count = 0;
-
- pool = fop->xl->ctx->iobuf_pool;
-
- pagesize = iobpool_default_pagesize(pool);
- maxsize = pagesize * ec->fragments;
+ ssize_t size = 0, bufsize = 0;
iobref = iobref_new();
if (iobref == NULL)
@@ -1951,43 +1943,30 @@ void ec_wind_writev(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
goto out;
}
- ptr = fop->vector[0].iov_base;
size = fop->vector[0].iov_len;
+ bufsize = size / ec->fragments;
- count = 0;
- while (size > 0)
+ iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, bufsize);
+ if (iobuf == NULL)
{
- iobuf = iobuf_get(pool);
- if (iobuf == NULL)
- {
- goto out;
- }
- if (iobref_add(iobref, iobuf) != 0)
- {
- goto out;
- }
-
- slice = size;
- if (slice > maxsize)
- {
- slice = maxsize;
- }
-
- ec_method_encode(slice, ec->fragments, idx, ptr, iobuf->ptr);
- ptr += slice;
+ goto out;
+ }
+ if (iobref_add(iobref, iobuf) != 0)
+ {
+ goto out;
+ }
- vector[count].iov_base = iobuf->ptr;
- vector[count].iov_len = slice / ec->fragments;
- count++;
+ ec_method_encode(size, ec->fragments, idx, fop->vector[0].iov_base,
+ iobuf->ptr);
- iobuf_unref(iobuf);
+ vector[0].iov_base = iobuf->ptr;
+ vector[0].iov_len = bufsize;
- size -= slice;
- }
+ iobuf_unref(iobuf);
STACK_WIND_COOKIE(fop->frame, ec_writev_cbk, (void *)(uintptr_t)idx,
ec->xl_list[idx], ec->xl_list[idx]->fops->writev,
- fop->fd, vector, count, fop->offset / ec->fragments,
+ fop->fd, vector, 1, fop->offset / ec->fragments,
fop->uint32, iobref, fop->xdata);
iobref_unref(iobref);