From 1125e8cbc072753fab78ba735bed3f29db61fcc4 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Thu, 11 Jun 2009 01:46:04 +0000 Subject: io-cache: handle memory allocation failures Signed-off-by: Anand V. Avati --- xlators/performance/io-cache/src/io-cache.c | 279 +++++++++++++++++++++++---- xlators/performance/io-cache/src/io-cache.h | 2 +- xlators/performance/io-cache/src/ioc-inode.c | 5 +- xlators/performance/io-cache/src/page.c | 152 ++++++++++++--- 4 files changed, 373 insertions(+), 65 deletions(-) diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index bab479b1ec8..b11d3728987 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -231,6 +231,14 @@ ioc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->file_loc.path); ioc_inode = ioc_inode_update (table, inode, weight); + if (ioc_inode == NULL) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory"); + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + inode_ctx_put (inode, this, (uint64_t)(long)ioc_inode); } @@ -254,18 +262,49 @@ ioc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, ioc_table_unlock (table); } else { page = ioc_page_create (ioc_inode, 0); + if (page == NULL) { + op_ret = -1; + op_errno = ENOMEM; + gf_log (this->name, + GF_LOG_ERROR, + "out of memory"); + goto out; + } } src = data_to_ptr (content_data); iobuf = iobuf_get (this->ctx->iobuf_pool); page->iobref = iobref_new (); + if (page->iobref == NULL) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory"); + + ioc_page_destroy (page); + page = NULL; + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + iobref_add (page->iobref, iobuf); memcpy (iobuf->ptr, src, stbuf->st_size); page->vector = CALLOC (1, sizeof (*page->vector)); + + if (page->vector == NULL) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory"); + + op_ret = -1; + op_errno = ENOMEM; + ioc_page_destroy (page); + page = NULL; + goto out; + } + page->vector->iov_base = iobuf->ptr; page->vector->iov_len = stbuf->st_size; page->count = 1; @@ -295,6 +334,14 @@ ioc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, return 0; } buf = CALLOC (1, stbuf->st_size); + if (buf == NULL) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory"); + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + tmp = buf; for (i = 0; i < page->count; i++) { @@ -308,9 +355,18 @@ ioc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->file_loc.path); if (!dict) { - need_unref = 1; - dict = dict_ref ( - get_new_dict ()); + dict = get_new_dict (); + if (dict == NULL) { + /* logged in get_new_dict() */ + FREE (buf); + buf = tmp = NULL; + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + + need_unref = 1; + dict_ref (dict); } dict_set (dict, "glusterfs.content", data_from_dynptr (buf, @@ -337,6 +393,7 @@ out: if (iobref) iobref_unref (iobref); + if (iobuf) iobuf_unref (iobuf); @@ -355,6 +412,13 @@ ioc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, if (GF_FILE_CONTENT_REQUESTED(xattr_req, &content_limit)) { local = CALLOC (1, sizeof (*local)); + if (local == NULL) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory"); + STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL, NULL); + return 0; + } + local->need_xattr = content_limit; local->file_loc.path = loc->path; local->file_loc.inode = loc->inode; @@ -482,6 +546,7 @@ ioc_wait_on_inode (ioc_inode_t *ioc_inode, ioc_page_t *page) { ioc_waitq_t *waiter = NULL, *trav = NULL; uint32_t page_found = 0; + int32_t ret = 0; trav = ioc_inode->waitq; @@ -495,13 +560,20 @@ ioc_wait_on_inode (ioc_inode_t *ioc_inode, ioc_page_t *page) if (!page_found) { waiter = CALLOC (1, sizeof (ioc_waitq_t)); - ERR_ABORT (waiter); + if (waiter == NULL) { + gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR, + "out of memory"); + ret = -ENOMEM; + goto out; + } + waiter->data = page; waiter->next = ioc_inode->waitq; ioc_inode->waitq = waiter; } - - return 0; + +out: + return ret; } /* @@ -518,10 +590,31 @@ ioc_cache_validate (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, { call_frame_t *validate_frame = NULL; ioc_local_t *validate_local = NULL; + ioc_local_t *local = NULL; + int32_t ret = 0; + local = frame->local; validate_local = CALLOC (1, sizeof (ioc_local_t)); - ERR_ABORT (validate_local); + if (validate_local == NULL) { + ret = -1; + local->op_ret = -1; + local->op_errno = ENOMEM; + gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR, + "out of memory"); + goto out; + } + validate_frame = copy_frame (frame); + if (validate_frame == NULL) { + ret = -1; + local->op_ret = -1; + local->op_errno = ENOMEM; + FREE (validate_local); + gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR, + "out of memory"); + goto out; + } + validate_local->fd = fd_ref (fd); validate_local->inode = ioc_inode; validate_frame->local = validate_local; @@ -530,20 +623,17 @@ ioc_cache_validate (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, FIRST_CHILD (frame->this), FIRST_CHILD (frame->this)->fops->fstat, fd); - return 0; +out: + return ret; } inline uint32_t is_match (const char *path, const char *pattern) { - char *pathname = NULL; int32_t ret = 0; - pathname = strdup (path); ret = fnmatch (pattern, path, FNM_NOESCAPE); - free (pathname); - return (ret == 0); } @@ -725,14 +815,18 @@ ioc_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, ioc_local_t *local = NULL; local = CALLOC (1, sizeof (ioc_local_t)); - ERR_ABORT (local); + if (local == NULL) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + STACK_UNWIND (frame, -1, ENOMEM, NULL); + return 0; + } local->flags = flags; local->file_loc.path = loc->path; local->file_loc.inode = loc->inode; frame->local = local; - + STACK_WIND (frame, ioc_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd); @@ -756,12 +850,16 @@ ioc_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, ioc_local_t *local = NULL; local = CALLOC (1, sizeof (ioc_local_t)); - ERR_ABORT (local); + if (local == NULL) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL, NULL); + return 0; + } local->flags = flags; local->file_loc.path = loc->path; frame->local = local; - + STACK_WIND (frame, ioc_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, fd); @@ -834,7 +932,7 @@ ioc_need_prune (ioc_table_t *table) */ void ioc_dispatch_requests (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, - off_t offset, size_t size) + off_t offset, size_t size) { ioc_local_t *local = NULL; ioc_table_t *table = NULL; @@ -846,6 +944,7 @@ ioc_dispatch_requests (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, int32_t fault = 0; size_t trav_size = 0; off_t local_offset = 0; + int32_t ret = -1; int8_t need_validate = 0; int8_t might_need_validate = 0; /* * if a page exists, do we need @@ -888,6 +987,9 @@ ioc_dispatch_requests (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, if (!trav) { gf_log (frame->this->name, GF_LOG_CRITICAL, "out of memory"); + local->op_ret = -1; + local->op_errno = ENOMEM; + goto out; } } @@ -908,7 +1010,20 @@ ioc_dispatch_requests (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, if (!ioc_inode->waitq) { need_validate = 1; } - ioc_wait_on_inode (ioc_inode, trav); + + ret = ioc_wait_on_inode (ioc_inode, trav); + if (ret < 0) { + local->op_ret = -1; + local->op_errno = -ret; + need_validate = 0; + + waitq = ioc_page_wakeup (trav); + ioc_inode_unlock (ioc_inode); + + ioc_waitq_return (waitq); + waitq = NULL; + goto out; + } } } @@ -930,12 +1045,24 @@ ioc_dispatch_requests (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, "sending validate request for " "inode(%"PRId64") at offset=%"PRId64"", fd->inode->ino, trav_offset); - ioc_cache_validate (frame, ioc_inode, fd, trav); + ret = ioc_cache_validate (frame, ioc_inode, fd, trav); + if (ret == -1) { + ioc_inode_lock (ioc_inode); + { + waitq = ioc_page_wakeup (trav); + } + ioc_inode_unlock (ioc_inode); + + ioc_waitq_return (waitq); + waitq = NULL; + goto out; + } } trav_offset += table->page_size; } +out: ioc_frame_return (frame); if (ioc_need_prune (ioc_inode->table)) { @@ -986,7 +1113,12 @@ ioc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, } local = (ioc_local_t *) CALLOC (1, sizeof (ioc_local_t)); - ERR_ABORT (local); + if (local == NULL) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + STACK_UNWIND (frame, -1, ENOMEM, NULL, 0, NULL, NULL); + return 0; + } + INIT_LIST_HEAD (&local->fill_list); frame->local = local; @@ -1061,7 +1193,12 @@ ioc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, uint64_t ioc_inode = 0; local = CALLOC (1, sizeof (ioc_local_t)); - ERR_ABORT (local); + if (local == NULL) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + + STACK_UNWIND (frame, -1, ENOMEM, NULL); + return 0; + } /* TODO: why is it not fd_ref'ed */ local->fd = fd; @@ -1192,9 +1329,14 @@ ioc_get_priority_list (const char *opt_str, struct list_head *first) char *pattern = NULL; char *priority = NULL; char *string = NULL; - struct ioc_priority *curr = NULL; + struct ioc_priority *curr = NULL, *tmp = NULL; string = strdup (opt_str); + if (string == NULL) { + max_pri = -1; + goto out; + } + /* Get the pattern for cache priority. * "option priority *.jpg:1,abc*:2" etc */ @@ -1204,28 +1346,71 @@ ioc_get_priority_list (const char *opt_str, struct list_head *first) stripe_str = strtok_r (string, ",", &tmp_str); while (stripe_str) { curr = CALLOC (1, sizeof (struct ioc_priority)); - ERR_ABORT (curr); + if (curr == NULL) { + max_pri = -1; + goto out; + } + list_add_tail (&curr->list, first); dup_str = strdup (stripe_str); + if (dup_str == NULL) { + max_pri = -1; + goto out; + } + pattern = strtok_r (dup_str, ":", &tmp_str1); - if (!pattern) - return -1; + if (!pattern) { + max_pri = -1; + goto out; + } + priority = strtok_r (NULL, ":", &tmp_str1); - if (!priority) - return -1; + if (!priority) { + max_pri = -1; + goto out; + } + gf_log ("io-cache", GF_LOG_TRACE, "ioc priority : pattern %s : priority %s", pattern, priority); + curr->pattern = strdup (pattern); + if (curr->pattern == NULL) { + max_pri = -1; + goto out; + } + curr->priority = strtol (priority, &tmp_str2, 0); - if (tmp_str2 && (*tmp_str2)) - return -1; - else - max_pri = max (max_pri, curr->priority); + if (tmp_str2 && (*tmp_str2)) { + max_pri = -1; + goto out; + } else { + max_pri = max (max_pri, curr->priority); + } + + free (dup_str); + dup_str = NULL; + stripe_str = strtok_r (NULL, ",", &tmp_str); } +out: + if (string != NULL) { + free (string); + } + + if (dup_str != NULL) { + free (dup_str); + } + + if (max_pri == -1) { + list_for_each_entry_safe (curr, tmp, first, list) { + list_del_init (&curr->list); + free (curr->pattern); + free (curr); + } + } return max_pri; } @@ -1242,12 +1427,13 @@ init (xlator_t *this) dict_t *options = this->options; uint32_t index = 0; char *cache_size_string = NULL; + int32_t ret = -1; if (!this->children || this->children->next) { gf_log (this->name, GF_LOG_ERROR, "FATAL: io-cache not configured with exactly " "one child"); - return -1; + goto out; } if (!this->parents) { @@ -1256,7 +1442,10 @@ init (xlator_t *this) } table = (void *) CALLOC (1, sizeof (*table)); - ERR_ABORT (table); + if (table == NULL) { + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto out; + } table->xl = this; table->page_size = this->ctx->page_size; @@ -1272,7 +1461,7 @@ init (xlator_t *this) "invalid number format \"%s\" of " "\"option cache-size\"", cache_size_string); - return -1; + goto out; } gf_log (this->name, GF_LOG_TRACE, @@ -1300,20 +1489,34 @@ init (xlator_t *this) table->max_pri = ioc_get_priority_list (option_list, &table->priority_list); - if (table->max_pri == -1) - return -1; + if (table->max_pri == -1) { + goto out; + } } table->max_pri ++; INIT_LIST_HEAD (&table->inodes); table->inode_lru = CALLOC (table->max_pri, sizeof (struct list_head)); - ERR_ABORT (table->inode_lru); + if (table->inode_lru == NULL) { + goto out; + } + for (index = 0; index < (table->max_pri); index++) INIT_LIST_HEAD (&table->inode_lru[index]); pthread_mutex_init (&table->table_lock, NULL); this->private = table; - return 0; + ret = 0; + +out: + if (ret == -1) { + if (table != NULL) { + free (table->inode_lru); + free (table); + } + } + + return ret; } /* diff --git a/xlators/performance/io-cache/src/io-cache.h b/xlators/performance/io-cache/src/io-cache.h index 5d0590d3311..82c01c1273f 100644 --- a/xlators/performance/io-cache/src/io-cache.h +++ b/xlators/performance/io-cache/src/io-cache.h @@ -215,7 +215,7 @@ ioc_frame_return (call_frame_t *frame); void ioc_waitq_return (ioc_waitq_t *waitq); -void +int32_t ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset, size_t size); diff --git a/xlators/performance/io-cache/src/ioc-inode.c b/xlators/performance/io-cache/src/ioc-inode.c index 60207720278..c131a48f2b7 100644 --- a/xlators/performance/io-cache/src/ioc-inode.c +++ b/xlators/performance/io-cache/src/ioc-inode.c @@ -150,7 +150,9 @@ ioc_inode_update (ioc_table_t *table, inode_t *inode, uint32_t weight) ioc_inode_t *ioc_inode = NULL; ioc_inode = CALLOC (1, sizeof (ioc_inode_t)); - ERR_ABORT (ioc_inode); + if (ioc_inode == NULL) { + goto out; + } ioc_inode->table = table; @@ -173,6 +175,7 @@ ioc_inode_update (ioc_table_t *table, inode_t *inode, uint32_t weight) pthread_mutex_init (&ioc_inode->inode_lock, NULL); ioc_inode->weight = weight; +out: return ioc_inode; } diff --git a/xlators/performance/io-cache/src/page.c b/xlators/performance/io-cache/src/page.c index be880344441..fc8c87618f8 100644 --- a/xlators/performance/io-cache/src/page.c +++ b/xlators/performance/io-cache/src/page.c @@ -203,12 +203,16 @@ ioc_page_create (ioc_inode_t *ioc_inode, off_t offset) rounded_offset = floor (offset, table->page_size); newpage = CALLOC (1, sizeof (*newpage)); - ERR_ABORT (newpage); + if (newpage == NULL) { + goto out; + } - if (ioc_inode) + if (ioc_inode) { table = ioc_inode->table; - else { - return NULL; + } else { + free (newpage); + newpage = NULL; + goto out; } newpage->offset = rounded_offset; @@ -222,6 +226,8 @@ ioc_page_create (ioc_inode_t *ioc_inode, off_t offset) gf_log ("io-cache", GF_LOG_TRACE, "returning new page %p", page); + +out: return page; } @@ -242,8 +248,13 @@ ioc_wait_on_page (ioc_page_t *page, call_frame_t *frame, off_t offset, ioc_local_t *local = frame->local; waitq = CALLOC (1, sizeof (*waitq)); - ERR_ABORT (waitq); - + if (waitq == NULL) { + local->op_ret = -1; + local->op_errno = ENOMEM; + gf_log (frame->this->name, GF_LOG_ERROR, "out of memory"); + goto out; + } + gf_log (frame->this->name, GF_LOG_TRACE, "frame(%p) waiting on page = %p, offset=%"PRId64", " "size=%"GF_PRI_SIZET"", @@ -261,6 +272,9 @@ ioc_wait_on_page (ioc_page_t *page, call_frame_t *frame, off_t offset, local->wait_count++; } ioc_local_unlock (local); + +out: + return; } @@ -385,6 +399,17 @@ ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* keep a copy of the page for our cache */ page->vector = iov_dup (vector, count); + if (page->vector == NULL) { + page = ioc_page_get (ioc_inode, offset); + if (page != NULL) + waitq = ioc_page_error (page, + -1, + ENOMEM); + op_ret = -1; + op_errno = ENOMEM; + goto unlock; + } + page->count = count; if (iobref) { page->iobref = iobref_ref (iobref); @@ -417,6 +442,7 @@ ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } /* if(!page)...else */ } /* if(op_ret < 0)...else */ } /* ioc_inode locked region end */ +unlock: ioc_inode_unlock (ioc_inode); ioc_waitq_return (waitq); @@ -466,11 +492,29 @@ ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd, ioc_table_t *table = NULL; call_frame_t *fault_frame = NULL; ioc_local_t *fault_local = NULL; + int32_t op_ret = -1, op_errno = -1; + ioc_waitq_t *waitq = NULL; + ioc_page_t *page = NULL; table = ioc_inode->table; fault_frame = copy_frame (frame); + if (fault_frame == NULL) { + op_ret = -1; + op_errno = ENOMEM; + gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR, + "out of memory"); + goto err; + } + fault_local = CALLOC (1, sizeof (ioc_local_t)); - ERR_ABORT (fault_local); + if (fault_local == NULL) { + op_ret = -1; + op_errno = ENOMEM; + STACK_DESTROY (fault_frame->root); + gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR, + "out of memory"); + goto err; + } /* NOTE: copy_frame() means, the frame the fop whose fd_ref we * are using till now won't be valid till we get reply from server. @@ -493,9 +537,18 @@ ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd, FIRST_CHILD(fault_frame->this)->fops->readv, fd, table->page_size, offset); return; + +err: + page = ioc_page_get (ioc_inode, offset); + if (page != NULL) { + waitq = ioc_page_error (page, op_ret, op_errno); + if (waitq != NULL) { + ioc_waitq_return (waitq); + } + } } -void +int32_t ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset, size_t size) { @@ -507,6 +560,7 @@ ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset, ioc_inode_t *ioc_inode = NULL; ioc_fill_t *new = NULL; int8_t found = 0; + int32_t ret = 0; local = frame->local; ioc_inode = page->inode; @@ -549,7 +603,15 @@ ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset, { new = CALLOC (1, sizeof (*new)); - ERR_ABORT (new); + if (new == NULL) { + local->op_ret = -1; + local->op_errno = ENOMEM; + ret = -1; + gf_log (page->inode->table->xl->name, + GF_LOG_ERROR, "out of memory"); + goto out; + } + new->offset = page->offset; new->size = copy_size; new->iobref = iobref_ref (page->iobref); @@ -558,9 +620,22 @@ ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset, src_offset, src_offset + copy_size, NULL); + new->vector = CALLOC (new->count, sizeof (struct iovec)); - ERR_ABORT (new->vector); + if (new->vector == NULL) { + local->op_ret = -1; + local->op_errno = ENOMEM; + + iobref_unref (new->iobref); + FREE (new); + + ret = -1; + gf_log (page->inode->table->xl->name, + GF_LOG_ERROR, "out of memory"); + goto out; + } + new->count = iov_subset (page->vector, page->count, src_offset, @@ -599,6 +674,9 @@ ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset, } local->op_ret += copy_size; } + +out: + return ret; } /* @@ -620,13 +698,17 @@ ioc_frame_unwind (call_frame_t *frame) int32_t copied = 0; struct iobref *iobref = NULL; struct stat stbuf = {0,}; - int32_t op_ret = 0; + int32_t op_ret = 0, op_errno = 0; local = frame->local; // ioc_local_lock (local); - iobref = iobref_new (); - frame->local = NULL; + iobref = iobref_new (); + if (iobref == NULL) { + op_ret = -1; + op_errno = ENOMEM; + gf_log (frame->this->name, GF_LOG_ERROR, "out of memory"); + } if (list_empty (&local->fill_list)) { gf_log (frame->this->name, GF_LOG_TRACE, @@ -640,16 +722,23 @@ ioc_frame_unwind (call_frame_t *frame) } vector = CALLOC (count, sizeof (*vector)); - ERR_ABORT (vector); + if (vector == NULL) { + op_ret = -1; + op_errno = ENOMEM; + + gf_log (frame->this->name, GF_LOG_ERROR, "out of memory"); + } list_for_each_entry_safe (fill, next, &local->fill_list, list) { - memcpy (((char *)vector) + copied, - fill->vector, - fill->count * sizeof (*vector)); + if ((vector != NULL) && (iobref != NULL)) { + memcpy (((char *)vector) + copied, + fill->vector, + fill->count * sizeof (*vector)); - copied += (fill->count * sizeof (*vector)); + copied += (fill->count * sizeof (*vector)); - iobref_merge (iobref, fill->iobref); + iobref_merge (iobref, fill->iobref); + } list_del (&fill->list); iobref_unref (fill->iobref); @@ -657,7 +746,10 @@ ioc_frame_unwind (call_frame_t *frame) free (fill); } - op_ret = iov_length (vector, count); + if (op_ret != -1) { + op_ret = iov_length (vector, count); + } + gf_log (frame->this->name, GF_LOG_TRACE, "frame(%p) unwinding with op_ret=%d", frame, op_ret); @@ -666,13 +758,19 @@ ioc_frame_unwind (call_frame_t *frame) STACK_UNWIND (frame, op_ret, local->op_errno, vector, count, &stbuf, iobref); - iobref_unref (iobref); + if (iobref != NULL) { + iobref_unref (iobref); + } + + if (vector != NULL) { + free (vector); + vector = NULL; + } pthread_mutex_destroy (&local->local_lock); free (local); - free (vector); - return; + return; } /* @@ -714,6 +812,7 @@ ioc_page_wakeup (ioc_page_t *page) { ioc_waitq_t *waitq = NULL, *trav = NULL; call_frame_t *frame = NULL; + int32_t ret = -1; waitq = page->waitq; page->waitq = NULL; @@ -726,8 +825,11 @@ ioc_page_wakeup (ioc_page_t *page) for (trav = waitq; trav; trav = trav->next) { frame = trav->data; - ioc_frame_fill (page, frame, trav->pending_offset, - trav->pending_size); + ret = ioc_frame_fill (page, frame, trav->pending_offset, + trav->pending_size); + if (ret == -1) { + break; + } } return waitq; -- cgit