diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
index 3d20e1d..6fb9261 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
@@ -2649,7 +2649,7 @@ static int
 arc_evict_needed(arc_buf_contents_t type)
 {
 	if (type == ARC_BUFC_METADATA && arc_meta_used >= arc_meta_limit)
-		return (1);
+		return (2);
 
 #ifdef sun
 #ifdef _KERNEL
@@ -2700,6 +2700,7 @@ arc_get_data_buf(arc_buf_t *buf)
 	arc_state_t		*state = buf->b_hdr->b_state;
 	uint64_t		size = buf->b_hdr->b_size;
 	arc_buf_contents_t	type = buf->b_hdr->b_type;
+	int			evict_needed;
 
 	arc_adapt(size, state);
 
@@ -2707,7 +2708,8 @@ arc_get_data_buf(arc_buf_t *buf)
 	 * We have not yet reached cache maximum size,
 	 * just allocate a new buffer.
 	 */
-	if (!arc_evict_needed(type)) {
+	evict_needed = arc_evict_needed(type);
+        if (!evict_needed) {
 		if (type == ARC_BUFC_METADATA) {
 			buf->b_data = zio_buf_alloc(size);
 			arc_space_consume(size, ARC_SPACE_DATA);
@@ -2739,7 +2741,19 @@ arc_get_data_buf(arc_buf_t *buf)
 		state =  (arc_mru->arcs_lsize[type] >= size &&
 		    mfu_space > arc_mfu->arcs_size) ? arc_mru : arc_mfu;
 	}
-	if ((buf->b_data = arc_evict(state, 0, size, TRUE, type)) == NULL) {
+
+	if (evict_needed == 1 && type == ARC_BUFC_METADATA) {
+		/* We are requesting a metadata buffer and the metadata cache
+		 * limit is not reached, we evict some data buffers and
+		 * continue to allocate a new metadata buffer.
+		 */
+		(void) arc_evict(state, 0, size, FALSE, ARC_BUFC_DATA);
+		buf->b_data = NULL;
+	} else {
+		buf->b_data = arc_evict(state, 0, size, TRUE, type);
+	}
+
+	if (buf->b_data == NULL) {
 		if (type == ARC_BUFC_METADATA) {
 			buf->b_data = zio_buf_alloc(size);
 			arc_space_consume(size, ARC_SPACE_DATA);
