changeset 7046 | 361307ae060d |
parent 6987 | 877c018eb06c |
child 7237 | f47d41541b14 |
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 |