| 6964 | } |
| 6965 | |
| 6966 | static void |
| 6967 | arc_write_done(zio_t *zio) |
| 6968 | { |
| 6969 | arc_write_callback_t *callback = zio->io_private; |
| 6970 | arc_buf_t *buf = callback->awcb_buf; |
| 6971 | arc_buf_hdr_t *hdr = buf->b_hdr; |
| 6972 | |
| 6973 | ASSERT3P(hdr->b_l1hdr.b_acb, ==, NULL); |
| 6974 | |
| 6975 | if (zio->io_error == 0) { |
| 6976 | arc_hdr_verify(hdr, zio->io_bp); |
| 6977 | |
| 6978 | if (BP_IS_HOLE(zio->io_bp) || BP_IS_EMBEDDED(zio->io_bp)) { |
| 6979 | buf_discard_identity(hdr); |
| 6980 | } else { |
| 6981 | hdr->b_dva = *BP_IDENTITY(zio->io_bp); |
| 6982 | hdr->b_birth = BP_PHYSICAL_BIRTH(zio->io_bp); |
| 6983 | } |
| 6984 | } else { |
| 6985 | ASSERT(HDR_EMPTY(hdr)); |
| 6986 | } |
| 6987 | |
| 6988 | /* |
| 6989 | * If the block to be written was all-zero or compressed enough to be |
| 6990 | * embedded in the BP, no write was performed so there will be no |
| 6991 | * dva/birth/checksum. The buffer must therefore remain anonymous |
| 6992 | * (and uncached). |
| 6993 | */ |
| 6994 | if (!HDR_EMPTY(hdr)) { |
| 6995 | arc_buf_hdr_t *exists; |
| 6996 | kmutex_t *hash_lock; |
| 6997 | |
| 6998 | ASSERT3U(zio->io_error, ==, 0); |
| 6999 | |
| 7000 | arc_cksum_verify(buf); |
| 7001 | |
| 7002 | exists = buf_hash_insert(hdr, &hash_lock); |
| 7003 | if (exists != NULL) { |
| 7004 | /* |
| 7005 | * This can only happen if we overwrite for |
| 7006 | * sync-to-convergence, because we remove |
| 7007 | * buffers from the hash table when we arc_free(). |
| 7008 | */ |
| 7009 | if (zio->io_flags & ZIO_FLAG_IO_REWRITE) { |
| 7010 | if (!BP_EQUAL(&zio->io_bp_orig, zio->io_bp)) |
| 7011 | panic("bad overwrite, hdr=%p exists=%p", |
| 7012 | (void *)hdr, (void *)exists); |
| 7013 | ASSERT(zfs_refcount_is_zero( |
| 7014 | &exists->b_l1hdr.b_refcnt)); |
| 7015 | arc_change_state(arc_anon, exists, hash_lock); |
| 7016 | arc_hdr_destroy(exists); |
| 7017 | mutex_exit(hash_lock); |
| 7018 | exists = buf_hash_insert(hdr, &hash_lock); |
| 7019 | ASSERT3P(exists, ==, NULL); |
| 7020 | } else if (zio->io_flags & ZIO_FLAG_NOPWRITE) { |
| 7021 | /* nopwrite */ |
| 7022 | ASSERT(zio->io_prop.zp_nopwrite); |
| 7023 | if (!BP_EQUAL(&zio->io_bp_orig, zio->io_bp)) |
nothing calls this directly
no test coverage detected