diff options
| author | Raghavendra G <raghavendra@zresearch.com> | 2009-06-11 01:46:04 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-06-11 08:01:14 -0700 | 
| commit | 1125e8cbc072753fab78ba735bed3f29db61fcc4 (patch) | |
| tree | 6069a8b2f62540bcb5347737971be0868f3255e2 /xlators/performance/io-cache/src/page.c | |
| parent | 180cfc0c4b6b9a46da35a536a565f010babfa4a7 (diff) | |
io-cache: handle memory allocation failures
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
Diffstat (limited to 'xlators/performance/io-cache/src/page.c')
| -rw-r--r-- | xlators/performance/io-cache/src/page.c | 152 | 
1 files changed, 127 insertions, 25 deletions
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;  | 
