usr/src/uts/common/fs/zfs/arc.c
changeset 7046 361307ae060d
parent 6987 877c018eb06c
child 7237 f47d41541b14
equal deleted inserted replaced
7045:d4292813278d 7046:361307ae060d
   171  * These tunables are for performance analysis.
   171  * These tunables are for performance analysis.
   172  */
   172  */
   173 uint64_t zfs_arc_max;
   173 uint64_t zfs_arc_max;
   174 uint64_t zfs_arc_min;
   174 uint64_t zfs_arc_min;
   175 uint64_t zfs_arc_meta_limit = 0;
   175 uint64_t zfs_arc_meta_limit = 0;
       
   176 int zfs_mdcomp_disable = 0;
   176 
   177 
   177 /*
   178 /*
   178  * Note that buffers can be in one of 6 states:
   179  * Note that buffers can be in one of 6 states:
   179  *	ARC_anon	- anonymous (discussed below)
   180  *	ARC_anon	- anonymous (discussed below)
   180  *	ARC_mru		- recently used, currently cached
   181  *	ARC_mru		- recently used, currently cached
   390 typedef struct arc_callback arc_callback_t;
   391 typedef struct arc_callback arc_callback_t;
   391 
   392 
   392 struct arc_callback {
   393 struct arc_callback {
   393 	void			*acb_private;
   394 	void			*acb_private;
   394 	arc_done_func_t		*acb_done;
   395 	arc_done_func_t		*acb_done;
   395 	arc_byteswap_func_t	*acb_byteswap;
       
   396 	arc_buf_t		*acb_buf;
   396 	arc_buf_t		*acb_buf;
   397 	zio_t			*acb_zio_dummy;
   397 	zio_t			*acb_zio_dummy;
   398 	arc_callback_t		*acb_next;
   398 	arc_callback_t		*acb_next;
   399 };
   399 };
   400 
   400 
   439 	/* self protecting */
   439 	/* self protecting */
   440 	refcount_t		b_refcnt;
   440 	refcount_t		b_refcnt;
   441 
   441 
   442 	l2arc_buf_hdr_t		*b_l2hdr;
   442 	l2arc_buf_hdr_t		*b_l2hdr;
   443 	list_node_t		b_l2node;
   443 	list_node_t		b_l2node;
       
   444 	/*
       
   445 	 * scrub code can lockout access to the buf while it changes
       
   446 	 * bp's contained within it.
       
   447 	 */
       
   448 	krwlock_t		b_datalock;
   444 };
   449 };
   445 
   450 
   446 static arc_buf_t *arc_eviction_list;
   451 static arc_buf_t *arc_eviction_list;
   447 static kmutex_t arc_eviction_mtx;
   452 static kmutex_t arc_eviction_mtx;
   448 static arc_buf_hdr_t arc_eviction_hdr;
   453 static arc_buf_hdr_t arc_eviction_hdr;
   472 #define	ARC_FREE_IN_PROGRESS	(1 << 15)	/* hdr about to be freed */
   477 #define	ARC_FREE_IN_PROGRESS	(1 << 15)	/* hdr about to be freed */
   473 #define	ARC_DONT_L2CACHE	(1 << 16)	/* originated by prefetch */
   478 #define	ARC_DONT_L2CACHE	(1 << 16)	/* originated by prefetch */
   474 #define	ARC_L2_WRITING		(1 << 17)	/* L2ARC write in progress */
   479 #define	ARC_L2_WRITING		(1 << 17)	/* L2ARC write in progress */
   475 #define	ARC_L2_EVICTED		(1 << 18)	/* evicted during I/O */
   480 #define	ARC_L2_EVICTED		(1 << 18)	/* evicted during I/O */
   476 #define	ARC_L2_WRITE_HEAD	(1 << 19)	/* head of write list */
   481 #define	ARC_L2_WRITE_HEAD	(1 << 19)	/* head of write list */
       
   482 #define	ARC_STORED		(1 << 20)	/* has been store()d to */
   477 
   483 
   478 #define	HDR_IN_HASH_TABLE(hdr)	((hdr)->b_flags & ARC_IN_HASH_TABLE)
   484 #define	HDR_IN_HASH_TABLE(hdr)	((hdr)->b_flags & ARC_IN_HASH_TABLE)
   479 #define	HDR_IO_IN_PROGRESS(hdr)	((hdr)->b_flags & ARC_IO_IN_PROGRESS)
   485 #define	HDR_IO_IN_PROGRESS(hdr)	((hdr)->b_flags & ARC_IO_IN_PROGRESS)
   480 #define	HDR_IO_ERROR(hdr)	((hdr)->b_flags & ARC_IO_ERROR)
   486 #define	HDR_IO_ERROR(hdr)	((hdr)->b_flags & ARC_IO_ERROR)
   481 #define	HDR_FREED_IN_READ(hdr)	((hdr)->b_flags & ARC_FREED_IN_READ)
   487 #define	HDR_FREED_IN_READ(hdr)	((hdr)->b_flags & ARC_FREED_IN_READ)
   607 static void l2arc_read_done(zio_t *zio);
   613 static void l2arc_read_done(zio_t *zio);
   608 static void l2arc_hdr_stat_add(void);
   614 static void l2arc_hdr_stat_add(void);
   609 static void l2arc_hdr_stat_remove(void);
   615 static void l2arc_hdr_stat_remove(void);
   610 
   616 
   611 static uint64_t
   617 static uint64_t
   612 buf_hash(spa_t *spa, dva_t *dva, uint64_t birth)
   618 buf_hash(spa_t *spa, const dva_t *dva, uint64_t birth)
   613 {
   619 {
   614 	uintptr_t spav = (uintptr_t)spa;
   620 	uintptr_t spav = (uintptr_t)spa;
   615 	uint8_t *vdva = (uint8_t *)dva;
   621 	uint8_t *vdva = (uint8_t *)dva;
   616 	uint64_t crc = -1ULL;
   622 	uint64_t crc = -1ULL;
   617 	int i;
   623 	int i;
   635 	((buf)->b_dva.dva_word[0] == (dva)->dva_word[0]) &&	\
   641 	((buf)->b_dva.dva_word[0] == (dva)->dva_word[0]) &&	\
   636 	((buf)->b_dva.dva_word[1] == (dva)->dva_word[1]) &&	\
   642 	((buf)->b_dva.dva_word[1] == (dva)->dva_word[1]) &&	\
   637 	((buf)->b_birth == birth) && ((buf)->b_spa == spa)
   643 	((buf)->b_birth == birth) && ((buf)->b_spa == spa)
   638 
   644 
   639 static arc_buf_hdr_t *
   645 static arc_buf_hdr_t *
   640 buf_hash_find(spa_t *spa, dva_t *dva, uint64_t birth, kmutex_t **lockp)
   646 buf_hash_find(spa_t *spa, const dva_t *dva, uint64_t birth, kmutex_t **lockp)
   641 {
   647 {
   642 	uint64_t idx = BUF_HASH_INDEX(spa, dva, birth);
   648 	uint64_t idx = BUF_HASH_INDEX(spa, dva, birth);
   643 	kmutex_t *hash_lock = BUF_HASH_LOCK(idx);
   649 	kmutex_t *hash_lock = BUF_HASH_LOCK(idx);
   644 	arc_buf_hdr_t *buf;
   650 	arc_buf_hdr_t *buf;
   645 
   651 
   755 
   761 
   756 	bzero(buf, sizeof (arc_buf_hdr_t));
   762 	bzero(buf, sizeof (arc_buf_hdr_t));
   757 	refcount_create(&buf->b_refcnt);
   763 	refcount_create(&buf->b_refcnt);
   758 	cv_init(&buf->b_cv, NULL, CV_DEFAULT, NULL);
   764 	cv_init(&buf->b_cv, NULL, CV_DEFAULT, NULL);
   759 	mutex_init(&buf->b_freeze_lock, NULL, MUTEX_DEFAULT, NULL);
   765 	mutex_init(&buf->b_freeze_lock, NULL, MUTEX_DEFAULT, NULL);
       
   766 	rw_init(&buf->b_datalock, NULL, RW_DEFAULT, NULL);
   760 
   767 
   761 	ARCSTAT_INCR(arcstat_hdr_size, HDR_SIZE);
   768 	ARCSTAT_INCR(arcstat_hdr_size, HDR_SIZE);
   762 	return (0);
   769 	return (0);
   763 }
   770 }
   764 
   771 
   773 	arc_buf_hdr_t *buf = vbuf;
   780 	arc_buf_hdr_t *buf = vbuf;
   774 
   781 
   775 	refcount_destroy(&buf->b_refcnt);
   782 	refcount_destroy(&buf->b_refcnt);
   776 	cv_destroy(&buf->b_cv);
   783 	cv_destroy(&buf->b_cv);
   777 	mutex_destroy(&buf->b_freeze_lock);
   784 	mutex_destroy(&buf->b_freeze_lock);
       
   785 	rw_destroy(&buf->b_datalock);
   778 
   786 
   779 	ARCSTAT_INCR(arcstat_hdr_size, -HDR_SIZE);
   787 	ARCSTAT_INCR(arcstat_hdr_size, -HDR_SIZE);
   780 }
   788 }
   781 
   789 
   782 /*
   790 /*
   939 		}
   947 		}
   940 		ASSERT(delta > 0);
   948 		ASSERT(delta > 0);
   941 		ASSERT3U(*size, >=, delta);
   949 		ASSERT3U(*size, >=, delta);
   942 		atomic_add_64(size, -delta);
   950 		atomic_add_64(size, -delta);
   943 		mutex_exit(&ab->b_state->arcs_mtx);
   951 		mutex_exit(&ab->b_state->arcs_mtx);
   944 		/* remove the prefetch flag is we get a reference */
   952 		/* remove the prefetch flag if we get a reference */
   945 		if (ab->b_flags & ARC_PREFETCH)
   953 		if (ab->b_flags & ARC_PREFETCH)
   946 			ab->b_flags &= ~ARC_PREFETCH;
   954 			ab->b_flags &= ~ARC_PREFETCH;
   947 	}
   955 	}
   948 }
   956 }
   949 
   957 
  1269 arc_hdr_destroy(arc_buf_hdr_t *hdr)
  1277 arc_hdr_destroy(arc_buf_hdr_t *hdr)
  1270 {
  1278 {
  1271 	ASSERT(refcount_is_zero(&hdr->b_refcnt));
  1279 	ASSERT(refcount_is_zero(&hdr->b_refcnt));
  1272 	ASSERT3P(hdr->b_state, ==, arc_anon);
  1280 	ASSERT3P(hdr->b_state, ==, arc_anon);
  1273 	ASSERT(!HDR_IO_IN_PROGRESS(hdr));
  1281 	ASSERT(!HDR_IO_IN_PROGRESS(hdr));
       
  1282 	ASSERT(!(hdr->b_flags & ARC_STORED));
  1274 
  1283 
  1275 	if (hdr->b_l2hdr != NULL) {
  1284 	if (hdr->b_l2hdr != NULL) {
  1276 		if (!MUTEX_HELD(&l2arc_buflist_mtx)) {
  1285 		if (!MUTEX_HELD(&l2arc_buflist_mtx)) {
  1277 			/*
  1286 			/*
  1278 			 * To prevent arc_free() and l2arc_evict() from
  1287 			 * To prevent arc_free() and l2arc_evict() from
  2294 		hdr->b_flags |= ARC_DONT_L2CACHE;
  2303 		hdr->b_flags |= ARC_DONT_L2CACHE;
  2295 
  2304 
  2296 	/* byteswap if necessary */
  2305 	/* byteswap if necessary */
  2297 	callback_list = hdr->b_acb;
  2306 	callback_list = hdr->b_acb;
  2298 	ASSERT(callback_list != NULL);
  2307 	ASSERT(callback_list != NULL);
  2299 	if (BP_SHOULD_BYTESWAP(zio->io_bp) && callback_list->acb_byteswap)
  2308 	if (BP_SHOULD_BYTESWAP(zio->io_bp)) {
  2300 		callback_list->acb_byteswap(buf->b_data, hdr->b_size);
  2309 		arc_byteswap_func_t *func = BP_GET_LEVEL(zio->io_bp) > 0 ?
       
  2310 		    byteswap_uint64_array :
       
  2311 		    dmu_ot[BP_GET_TYPE(zio->io_bp)].ot_byteswap;
       
  2312 		func(buf->b_data, hdr->b_size);
       
  2313 	}
  2301 
  2314 
  2302 	arc_cksum_compute(buf, B_FALSE);
  2315 	arc_cksum_compute(buf, B_FALSE);
  2303 
  2316 
  2304 	/* create copies of the data buffer for the callers */
  2317 	/* create copies of the data buffer for the callers */
  2305 	abuf = buf;
  2318 	abuf = buf;
  2392  * to the read to invoke the "done" func when the read completes,
  2405  * to the read to invoke the "done" func when the read completes,
  2393  * and return; or just return.
  2406  * and return; or just return.
  2394  *
  2407  *
  2395  * arc_read_done() will invoke all the requested "done" functions
  2408  * arc_read_done() will invoke all the requested "done" functions
  2396  * for readers of this block.
  2409  * for readers of this block.
       
  2410  *
       
  2411  * Normal callers should use arc_read and pass the arc buffer and offset
       
  2412  * for the bp.  But if you know you don't need locking, you can use
       
  2413  * arc_read_bp.
  2397  */
  2414  */
  2398 int
  2415 int
  2399 arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_byteswap_func_t *swap,
  2416 arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf,
  2400     arc_done_func_t *done, void *private, int priority, int flags,
  2417     arc_done_func_t *done, void *private, int priority, int flags,
  2401     uint32_t *arc_flags, zbookmark_t *zb)
  2418     uint32_t *arc_flags, const zbookmark_t *zb)
       
  2419 {
       
  2420 	int err;
       
  2421 
       
  2422 	ASSERT(!refcount_is_zero(&pbuf->b_hdr->b_refcnt));
       
  2423 	ASSERT3U((char *)bp - (char *)pbuf->b_data, <, pbuf->b_hdr->b_size);
       
  2424 	rw_enter(&pbuf->b_hdr->b_datalock, RW_READER);
       
  2425 
       
  2426 	err = arc_read_nolock(pio, spa, bp, done, private, priority,
       
  2427 	    flags, arc_flags, zb);
       
  2428 
       
  2429 	rw_exit(&pbuf->b_hdr->b_datalock);
       
  2430 	return (err);
       
  2431 }
       
  2432 
       
  2433 int
       
  2434 arc_read_nolock(zio_t *pio, spa_t *spa, blkptr_t *bp,
       
  2435     arc_done_func_t *done, void *private, int priority, int flags,
       
  2436     uint32_t *arc_flags, const zbookmark_t *zb)
  2402 {
  2437 {
  2403 	arc_buf_hdr_t *hdr;
  2438 	arc_buf_hdr_t *hdr;
  2404 	arc_buf_t *buf;
  2439 	arc_buf_t *buf;
  2405 	kmutex_t *hash_lock;
  2440 	kmutex_t *hash_lock;
  2406 	zio_t *rzio;
  2441 	zio_t *rzio;
  2425 
  2460 
  2426 				acb = kmem_zalloc(sizeof (arc_callback_t),
  2461 				acb = kmem_zalloc(sizeof (arc_callback_t),
  2427 				    KM_SLEEP);
  2462 				    KM_SLEEP);
  2428 				acb->acb_done = done;
  2463 				acb->acb_done = done;
  2429 				acb->acb_private = private;
  2464 				acb->acb_private = private;
  2430 				acb->acb_byteswap = swap;
       
  2431 				if (pio != NULL)
  2465 				if (pio != NULL)
  2432 					acb->acb_zio_dummy = zio_null(pio,
  2466 					acb->acb_zio_dummy = zio_null(pio,
  2433 					    spa, NULL, NULL, flags);
  2467 					    spa, NULL, NULL, flags);
  2434 
  2468 
  2435 				ASSERT(acb->acb_done != NULL);
  2469 				ASSERT(acb->acb_done != NULL);
  2534 		}
  2568 		}
  2535 
  2569 
  2536 		acb = kmem_zalloc(sizeof (arc_callback_t), KM_SLEEP);
  2570 		acb = kmem_zalloc(sizeof (arc_callback_t), KM_SLEEP);
  2537 		acb->acb_done = done;
  2571 		acb->acb_done = done;
  2538 		acb->acb_private = private;
  2572 		acb->acb_private = private;
  2539 		acb->acb_byteswap = swap;
       
  2540 
  2573 
  2541 		ASSERT(hdr->b_acb == NULL);
  2574 		ASSERT(hdr->b_acb == NULL);
  2542 		hdr->b_acb = acb;
  2575 		hdr->b_acb = acb;
  2543 		hdr->b_flags |= ARC_IO_IN_PROGRESS;
  2576 		hdr->b_flags |= ARC_IO_IN_PROGRESS;
  2544 
  2577 
  2788 
  2821 
  2789 /*
  2822 /*
  2790  * Release this buffer from the cache.  This must be done
  2823  * Release this buffer from the cache.  This must be done
  2791  * after a read and prior to modifying the buffer contents.
  2824  * after a read and prior to modifying the buffer contents.
  2792  * If the buffer has more than one reference, we must make
  2825  * If the buffer has more than one reference, we must make
  2793  * make a new hdr for the buffer.
  2826  * a new hdr for the buffer.
  2794  */
  2827  */
  2795 void
  2828 void
  2796 arc_release(arc_buf_t *buf, void *tag)
  2829 arc_release(arc_buf_t *buf, void *tag)
  2797 {
  2830 {
  2798 	arc_buf_hdr_t *hdr = buf->b_hdr;
  2831 	arc_buf_hdr_t *hdr = buf->b_hdr;
  2800 	l2arc_buf_hdr_t *l2hdr = NULL;
  2833 	l2arc_buf_hdr_t *l2hdr = NULL;
  2801 	uint64_t buf_size;
  2834 	uint64_t buf_size;
  2802 
  2835 
  2803 	/* this buffer is not on any list */
  2836 	/* this buffer is not on any list */
  2804 	ASSERT(refcount_count(&hdr->b_refcnt) > 0);
  2837 	ASSERT(refcount_count(&hdr->b_refcnt) > 0);
       
  2838 	ASSERT(!(hdr->b_flags & ARC_STORED));
  2805 
  2839 
  2806 	if (hdr->b_state == arc_anon) {
  2840 	if (hdr->b_state == arc_anon) {
  2807 		/* this buffer is already released */
  2841 		/* this buffer is already released */
  2808 		ASSERT3U(refcount_count(&hdr->b_refcnt), ==, 1);
  2842 		ASSERT3U(refcount_count(&hdr->b_refcnt), ==, 1);
  2809 		ASSERT(BUF_EMPTY(hdr));
  2843 		ASSERT(BUF_EMPTY(hdr));
  2962 	arc_buf_t *buf = callback->awcb_buf;
  2996 	arc_buf_t *buf = callback->awcb_buf;
  2963 	arc_buf_hdr_t *hdr = buf->b_hdr;
  2997 	arc_buf_hdr_t *hdr = buf->b_hdr;
  2964 
  2998 
  2965 	hdr->b_acb = NULL;
  2999 	hdr->b_acb = NULL;
  2966 
  3000 
  2967 	/* this buffer is on no lists and is not in the hash table */
       
  2968 	ASSERT3P(hdr->b_state, ==, arc_anon);
       
  2969 
       
  2970 	hdr->b_dva = *BP_IDENTITY(zio->io_bp);
  3001 	hdr->b_dva = *BP_IDENTITY(zio->io_bp);
  2971 	hdr->b_birth = zio->io_bp->blk_birth;
  3002 	hdr->b_birth = zio->io_bp->blk_birth;
  2972 	hdr->b_cksum0 = zio->io_bp->blk_cksum.zc_word[0];
  3003 	hdr->b_cksum0 = zio->io_bp->blk_cksum.zc_word[0];
  2973 	/*
  3004 	/*
  2974 	 * If the block to be written was all-zero, we may have
  3005 	 * If the block to be written was all-zero, we may have
  3000 			arc_hdr_destroy(exists);
  3031 			arc_hdr_destroy(exists);
  3001 			exists = buf_hash_insert(hdr, &hash_lock);
  3032 			exists = buf_hash_insert(hdr, &hash_lock);
  3002 			ASSERT3P(exists, ==, NULL);
  3033 			ASSERT3P(exists, ==, NULL);
  3003 		}
  3034 		}
  3004 		hdr->b_flags &= ~ARC_IO_IN_PROGRESS;
  3035 		hdr->b_flags &= ~ARC_IO_IN_PROGRESS;
  3005 		arc_access(hdr, hash_lock);
  3036 		/* if it's not anon, we are doing a scrub */
       
  3037 		if (hdr->b_state == arc_anon)
       
  3038 			arc_access(hdr, hash_lock);
  3006 		mutex_exit(hash_lock);
  3039 		mutex_exit(hash_lock);
  3007 	} else if (callback->awcb_done == NULL) {
  3040 	} else if (callback->awcb_done == NULL) {
  3008 		int destroy_hdr;
  3041 		int destroy_hdr;
  3009 		/*
  3042 		/*
  3010 		 * This is an anonymous buffer with no user callback,
  3043 		 * This is an anonymous buffer with no user callback,
  3017 		if (destroy_hdr)
  3050 		if (destroy_hdr)
  3018 			arc_hdr_destroy(hdr);
  3051 			arc_hdr_destroy(hdr);
  3019 	} else {
  3052 	} else {
  3020 		hdr->b_flags &= ~ARC_IO_IN_PROGRESS;
  3053 		hdr->b_flags &= ~ARC_IO_IN_PROGRESS;
  3021 	}
  3054 	}
       
  3055 	hdr->b_flags &= ~ARC_STORED;
  3022 
  3056 
  3023 	if (callback->awcb_done) {
  3057 	if (callback->awcb_done) {
  3024 		ASSERT(!refcount_is_zero(&hdr->b_refcnt));
  3058 		ASSERT(!refcount_is_zero(&hdr->b_refcnt));
  3025 		callback->awcb_done(zio, buf, callback->awcb_private);
  3059 		callback->awcb_done(zio, buf, callback->awcb_private);
  3026 	}
  3060 	}
  3027 
  3061 
  3028 	kmem_free(callback, sizeof (arc_write_callback_t));
  3062 	kmem_free(callback, sizeof (arc_write_callback_t));
  3029 }
  3063 }
  3030 
  3064 
       
  3065 static void
       
  3066 write_policy(spa_t *spa, const writeprops_t *wp,
       
  3067     int *cksump, int *compp, int *copiesp)
       
  3068 {
       
  3069 	int copies = wp->wp_copies;
       
  3070 	boolean_t ismd = (wp->wp_level > 0 || dmu_ot[wp->wp_type].ot_metadata);
       
  3071 
       
  3072 	/* Determine copies setting */
       
  3073 	if (ismd)
       
  3074 		copies++;
       
  3075 	*copiesp = MIN(copies, spa_max_replication(spa));
       
  3076 
       
  3077 	/* Determine checksum setting */
       
  3078 	if (ismd) {
       
  3079 		/*
       
  3080 		 * Metadata always gets checksummed.  If the data
       
  3081 		 * checksum is multi-bit correctable, and it's not a
       
  3082 		 * ZBT-style checksum, then it's suitable for metadata
       
  3083 		 * as well.  Otherwise, the metadata checksum defaults
       
  3084 		 * to fletcher4.
       
  3085 		 */
       
  3086 		if (zio_checksum_table[wp->wp_oschecksum].ci_correctable &&
       
  3087 		    !zio_checksum_table[wp->wp_oschecksum].ci_zbt)
       
  3088 			*cksump = wp->wp_oschecksum;
       
  3089 		else
       
  3090 			*cksump = ZIO_CHECKSUM_FLETCHER_4;
       
  3091 	} else {
       
  3092 		*cksump = zio_checksum_select(wp->wp_dnchecksum,
       
  3093 		    wp->wp_oschecksum);
       
  3094 	}
       
  3095 
       
  3096 	/* Determine compression setting */
       
  3097 	if (ismd) {
       
  3098 		/*
       
  3099 		 * XXX -- we should design a compression algorithm
       
  3100 		 * that specializes in arrays of bps.
       
  3101 		 */
       
  3102 		*compp = zfs_mdcomp_disable ? ZIO_COMPRESS_EMPTY :
       
  3103 		    ZIO_COMPRESS_LZJB;
       
  3104 	} else {
       
  3105 		*compp = zio_compress_select(wp->wp_dncompress,
       
  3106 		    wp->wp_oscompress);
       
  3107 	}
       
  3108 }
       
  3109 
  3031 zio_t *
  3110 zio_t *
  3032 arc_write(zio_t *pio, spa_t *spa, int checksum, int compress, int ncopies,
  3111 arc_write(zio_t *pio, spa_t *spa, const writeprops_t *wp,
  3033     uint64_t txg, blkptr_t *bp, arc_buf_t *buf,
  3112     uint64_t txg, blkptr_t *bp, arc_buf_t *buf,
  3034     arc_done_func_t *ready, arc_done_func_t *done, void *private, int priority,
  3113     arc_done_func_t *ready, arc_done_func_t *done, void *private, int priority,
  3035     int flags, zbookmark_t *zb)
  3114     int flags, const zbookmark_t *zb)
  3036 {
  3115 {
  3037 	arc_buf_hdr_t *hdr = buf->b_hdr;
  3116 	arc_buf_hdr_t *hdr = buf->b_hdr;
  3038 	arc_write_callback_t *callback;
  3117 	arc_write_callback_t *callback;
  3039 	zio_t	*zio;
  3118 	zio_t	*zio;
  3040 
  3119 	int cksum, comp, copies;
  3041 	/* this is a private buffer - no locking required */
  3120 
  3042 	ASSERT3P(hdr->b_state, ==, arc_anon);
       
  3043 	ASSERT(BUF_EMPTY(hdr));
       
  3044 	ASSERT(!HDR_IO_ERROR(hdr));
  3121 	ASSERT(!HDR_IO_ERROR(hdr));
  3045 	ASSERT((hdr->b_flags & ARC_IO_IN_PROGRESS) == 0);
  3122 	ASSERT((hdr->b_flags & ARC_IO_IN_PROGRESS) == 0);
  3046 	ASSERT(hdr->b_acb == 0);
  3123 	ASSERT(hdr->b_acb == 0);
  3047 	callback = kmem_zalloc(sizeof (arc_write_callback_t), KM_SLEEP);
  3124 	callback = kmem_zalloc(sizeof (arc_write_callback_t), KM_SLEEP);
  3048 	callback->awcb_ready = ready;
  3125 	callback->awcb_ready = ready;
  3049 	callback->awcb_done = done;
  3126 	callback->awcb_done = done;
  3050 	callback->awcb_private = private;
  3127 	callback->awcb_private = private;
  3051 	callback->awcb_buf = buf;
  3128 	callback->awcb_buf = buf;
  3052 	zio = zio_write(pio, spa, checksum, compress, ncopies, txg, bp,
  3129 
  3053 	    buf->b_data, hdr->b_size, arc_write_ready, arc_write_done, callback,
  3130 	write_policy(spa, wp, &cksum, &comp, &copies);
  3054 	    priority, flags, zb);
  3131 	zio = zio_write(pio, spa, cksum, comp, copies, txg, bp,
       
  3132 	    buf->b_data, hdr->b_size, arc_write_ready, arc_write_done,
       
  3133 	    callback, priority, flags, zb);
  3055 
  3134 
  3056 	return (zio);
  3135 	return (zio);
  3057 }
  3136 }
  3058 
  3137 
  3059 int
  3138 int