MCPcopy Create free account
hub / github.com/F-Stack/f-stack / zil_lwb_write_done

Function zil_lwb_write_done

freebsd/contrib/openzfs/module/zfs/zil.c:1212–1286  ·  view source on GitHub ↗

* This is called when an lwb's write zio completes. The callback's * purpose is to issue the DKIOCFLUSHWRITECACHE commands for the vdevs * in the lwb's lwb_vdev_tree. The tree will contain the vdevs involved * in writing out this specific lwb's data, and in the case that cache * flushes have been deferred, vdevs involved in writing the data for * previous lwbs. The writes corresponding to all

Source from the content-addressed store, hash-verified

1210 * completion callback for the lwb's root zio.
1211 */
1212static void
1213zil_lwb_write_done(zio_t *zio)
1214{
1215 lwb_t *lwb = zio->io_private;
1216 spa_t *spa = zio->io_spa;
1217 zilog_t *zilog = lwb->lwb_zilog;
1218 avl_tree_t *t = &lwb->lwb_vdev_tree;
1219 void *cookie = NULL;
1220 zil_vdev_node_t *zv;
1221 lwb_t *nlwb;
1222
1223 ASSERT3S(spa_config_held(spa, SCL_STATE, RW_READER), !=, 0);
1224
1225 ASSERT(BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_OFF);
1226 ASSERT(BP_GET_TYPE(zio->io_bp) == DMU_OT_INTENT_LOG);
1227 ASSERT(BP_GET_LEVEL(zio->io_bp) == 0);
1228 ASSERT(BP_GET_BYTEORDER(zio->io_bp) == ZFS_HOST_BYTEORDER);
1229 ASSERT(!BP_IS_GANG(zio->io_bp));
1230 ASSERT(!BP_IS_HOLE(zio->io_bp));
1231 ASSERT(BP_GET_FILL(zio->io_bp) == 0);
1232
1233 abd_put(zio->io_abd);
1234
1235 mutex_enter(&zilog->zl_lock);
1236 ASSERT3S(lwb->lwb_state, ==, LWB_STATE_ISSUED);
1237 lwb->lwb_state = LWB_STATE_WRITE_DONE;
1238 lwb->lwb_write_zio = NULL;
1239 lwb->lwb_fastwrite = FALSE;
1240 nlwb = list_next(&zilog->zl_lwb_list, lwb);
1241 mutex_exit(&zilog->zl_lock);
1242
1243 if (avl_numnodes(t) == 0)
1244 return;
1245
1246 /*
1247 * If there was an IO error, we're not going to call zio_flush()
1248 * on these vdevs, so we simply empty the tree and free the
1249 * nodes. We avoid calling zio_flush() since there isn't any
1250 * good reason for doing so, after the lwb block failed to be
1251 * written out.
1252 */
1253 if (zio->io_error != 0) {
1254 while ((zv = avl_destroy_nodes(t, &cookie)) != NULL)
1255 kmem_free(zv, sizeof (*zv));
1256 return;
1257 }
1258
1259 /*
1260 * If this lwb does not have any threads waiting for it to
1261 * complete, we want to defer issuing the DKIOCFLUSHWRITECACHE
1262 * command to the vdevs written to by "this" lwb, and instead
1263 * rely on the "next" lwb to handle the DKIOCFLUSHWRITECACHE
1264 * command for those vdevs. Thus, we merge the vdev tree of
1265 * "this" lwb with the vdev tree of the "next" lwb in the list,
1266 * and assume the "next" lwb will handle flushing the vdevs (or
1267 * deferring the flush(s) again).
1268 *
1269 * This is a useful performance optimization, especially for

Callers

nothing calls this directly

Calls 13

spa_config_heldFunction · 0.85
abd_putFunction · 0.85
mutex_enterFunction · 0.85
mutex_exitFunction · 0.85
avl_numnodesFunction · 0.85
avl_destroy_nodesFunction · 0.85
zil_lwb_flush_deferFunction · 0.85
avl_is_emptyFunction · 0.85
vdev_lookup_topFunction · 0.85
zio_flushFunction · 0.85
list_nextFunction · 0.50
kmem_freeFunction · 0.50

Tested by

no test coverage detected