From 3524572538e5abe839fa29fe94da8f7591cedce8 Mon Sep 17 00:00:00 2001 From: "Anand V. Avati" Date: Sat, 11 Apr 2009 00:09:08 +0530 Subject: IOBREF support for holding iobuf refs along with fops (replacement for frame->root->{req,rsp}_refs Signed-off-by: Anand V. Avati --- libglusterfs/src/iobuf.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) (limited to 'libglusterfs/src/iobuf.c') diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c index 5d1f37c0..b11438b3 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -392,3 +392,142 @@ iobuf_ref (struct iobuf *iobuf) return iobuf; } + + +struct iobref * +iobref_new () +{ + struct iobref *iobref = NULL; + + iobref = CALLOC (sizeof (*iobref), 1); + if (!iobref) + return NULL; + + LOCK_INIT (&iobref->lock); + + iobref->ref++; + + return iobref; +} + + +struct iobref * +iobref_ref (struct iobref *iobref) +{ + if (!iobref) + return NULL; + + LOCK (&iobref->lock); + { + iobref->ref++; + } + UNLOCK (&iobref->lock); + + return iobref; +} + + +void +iobref_destroy (struct iobref *iobref) +{ + int i = 0; + struct iobuf *iobuf = NULL; + + if (!iobref) + return; + + for (i = 0; i < 8; i++) { + iobuf = iobref->iobrefs[i]; + + iobref->iobrefs[i] = NULL; + if (iobuf) + iobuf_unref (iobuf); + } + + FREE (iobref); +} + + +void +iobref_unref (struct iobref *iobref) +{ + int ref = 0; + + if (!iobref) + return; + + LOCK (&iobref->lock); + { + ref = (--iobref->ref); + } + UNLOCK (&iobref->lock); + + if (!ref) + iobref_destroy (iobref); +} + + +int +__iobref_add (struct iobref *iobref, struct iobuf *iobuf) +{ + int i = 0; + int ret = -ENOMEM; + + for (i = 0; i < 8; i++) { + if (iobref->iobrefs[i] == NULL) { + iobref->iobrefs[i] = iobuf_ref (iobuf); + ret = 0; + break; + } + } + + return ret; +} + + +int +iobref_add (struct iobref *iobref, struct iobuf *iobuf) +{ + int ret = 0; + + if (!iobref) + return -EINVAL; + + if (!iobuf) + return -EINVAL; + + LOCK (&iobref->lock); + { + ret = __iobref_add (iobref, iobuf); + } + UNLOCK (&iobref->lock); + + return ret; +} + + +int +iobref_merge (struct iobref *to, struct iobref *from) +{ + int i = 0; + int ret = 0; + struct iobuf *iobuf = NULL; + + LOCK (&from->lock); + { + for (i = 0; i < 8; i++) { + iobuf = from->iobrefs[i]; + + if (!iobuf) + break; + + ret = iobref_add (to, iobuf); + + if (ret < 0) + break; + } + } + UNLOCK (&from->lock); + + return ret; +} -- cgit