From c9579c4501a5d316f71fc44fd46a53060a4eed0c Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Mon, 25 Nov 2013 03:08:19 -0800 Subject: iobufs: make iobref container size dynamic With gfapi we can receive read/write size beyond the natural limits of FUSE and NFS server. iobref was hardcoded to hold iobuf refs up to 16 in count, which imposes a natural limit of 2MB with 128KB page sizes of read-ahead and io-cache. Fix this by making iobref's iobuf ref container size dynamic. Change-Id: I93d88104d6c5e7af96cc9f1bfcc870d80fa81dad BUG: 1034398 Signed-off-by: Anand Avati Reviewed-on: http://review.gluster.org/6348 Tested-by: Gluster Build System Reviewed-by: Amar Tumballi --- libglusterfs/src/iobuf.c | 49 +++++++++++++++++++++++++++++++++++++++----- libglusterfs/src/iobuf.h | 5 +++-- libglusterfs/src/mem-types.h | 3 ++- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c index a89e96267..82ffe2dd8 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -773,6 +773,16 @@ iobref_new () if (!iobref) return NULL; + iobref->iobrefs = GF_CALLOC (sizeof (*iobref->iobrefs), + 16, gf_common_mt_iobrefs); + if (!iobref->iobrefs) { + GF_FREE (iobref); + return NULL; + } + + iobref->alloced = 16; + iobref->used = 0; + LOCK_INIT (&iobref->lock); iobref->ref++; @@ -805,7 +815,7 @@ iobref_destroy (struct iobref *iobref) GF_VALIDATE_OR_GOTO ("iobuf", iobref, out); - for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) { + for (i = 0; i < iobref->alloced; i++) { iobuf = iobref->iobrefs[i]; iobref->iobrefs[i] = NULL; @@ -813,6 +823,7 @@ iobref_destroy (struct iobref *iobref) iobuf_unref (iobuf); } + GF_FREE (iobref->iobrefs); GF_FREE (iobref); out: @@ -848,7 +859,7 @@ iobref_clear (struct iobref *iobref) GF_VALIDATE_OR_GOTO ("iobuf", iobref, out); - for (; i < GF_IOBREF_IOBUF_COUNT; i++) { + for (; i < iobref->alloced; i++) { if (iobref->iobrefs[i] != NULL) { iobuf_unref (iobref->iobrefs[i]); } else { @@ -864,6 +875,24 @@ iobref_clear (struct iobref *iobref) } +static void +__iobref_grow (struct iobref *iobref) +{ + void *newptr = NULL; + int i = 0; + + newptr = GF_REALLOC (iobref->iobrefs, + iobref->alloced * 2 * (sizeof (*iobref->iobrefs))); + if (newptr) { + iobref->iobrefs = newptr; + iobref->alloced *= 2; + + for (i = iobref->used; i < iobref->alloced; i++) + iobref->iobrefs[i] = NULL; + } +} + + int __iobref_add (struct iobref *iobref, struct iobuf *iobuf) { @@ -873,9 +902,19 @@ __iobref_add (struct iobref *iobref, struct iobuf *iobuf) GF_VALIDATE_OR_GOTO ("iobuf", iobref, out); GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out); - for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) { + if (iobref->used == iobref->alloced) { + __iobref_grow (iobref); + + if (iobref->used == iobref->alloced) { + ret = -ENOMEM; + goto out; + } + } + + for (i = 0; i < iobref->alloced; i++) { if (iobref->iobrefs[i] == NULL) { iobref->iobrefs[i] = iobuf_ref (iobuf); + iobref->used++; ret = 0; break; } @@ -917,7 +956,7 @@ iobref_merge (struct iobref *to, struct iobref *from) LOCK (&from->lock); { - for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) { + for (i = 0; i < from->alloced; i++) { iobuf = from->iobrefs[i]; if (!iobuf) @@ -969,7 +1008,7 @@ iobref_size (struct iobref *iobref) LOCK (&iobref->lock); { - for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) { + for (i = 0; i < iobref->alloced; i++) { if (iobref->iobrefs[i]) size += iobuf_size (iobref->iobrefs[i]); } diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h index 5595309e1..4e07910d7 100644 --- a/libglusterfs/src/iobuf.h +++ b/libglusterfs/src/iobuf.h @@ -18,7 +18,6 @@ #include #define GF_VARIABLE_IOBUF_COUNT 32 -#define GF_IOBREF_IOBUF_COUNT 16 /* Lets try to define the new anonymous mapping * flag, in case the system is still using the @@ -142,7 +141,9 @@ void iobuf_to_iovec(struct iobuf *iob, struct iovec *iov); struct iobref { gf_lock_t lock; int ref; - struct iobuf *iobrefs[GF_IOBREF_IOBUF_COUNT]; + struct iobuf **iobrefs; + int alloced; + int used; }; struct iobref *iobref_new (); diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h index 9aadbcaec..fc0aa9018 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -117,6 +117,7 @@ enum gf_common_mem_types_ { gf_common_mt_locker = 101, gf_common_mt_auxgids = 102, gf_common_mt_syncopctx = 103, - gf_common_mt_end = 104 + gf_common_mt_iobrefs = 104, + gf_common_mt_end = 105 }; #endif -- cgit