diff options
Diffstat (limited to 'xlators/performance/io-cache/src')
| -rw-r--r-- | xlators/performance/io-cache/src/io-cache.c | 279 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/io-cache.h | 2 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/ioc-inode.c | 5 | ||||
| -rw-r--r-- | 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 bab479b1e..b11d37289 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 5d0590d33..82c01c127 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 602077202..c131a48f2 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 be8803444..fc8c87618 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;  | 
