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

Function vdev_label_read_config

freebsd/contrib/openzfs/module/zfs/vdev_label.c:752–837  ·  view source on GitHub ↗

* Returns the configuration from the label of the given vdev. For vdevs * which don't have a txg value stored on their label (i.e. spares/cache) * or have not been completely initialized (txg = 0) just return * the configuration from the first valid label we find. Otherwise, * find the most up-to-date label that does not exceed the specified * 'txg' value. */

Source from the content-addressed store, hash-verified

750 * 'txg' value.
751 */
752nvlist_t *
753vdev_label_read_config(vdev_t *vd, uint64_t txg)
754{
755 spa_t *spa = vd->vdev_spa;
756 nvlist_t *config = NULL;
757 vdev_phys_t *vp;
758 abd_t *vp_abd;
759 zio_t *zio;
760 uint64_t best_txg = 0;
761 uint64_t label_txg = 0;
762 int error = 0;
763 int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
764 ZIO_FLAG_SPECULATIVE;
765
766 ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
767
768 if (!vdev_readable(vd))
769 return (NULL);
770
771 /*
772 * The label for a dRAID distributed spare is not stored on disk.
773 * Instead it is generated when needed which allows us to bypass
774 * the pipeline when reading the config from the label.
775 */
776 if (vd->vdev_ops == &vdev_draid_spare_ops)
777 return (vdev_draid_read_config_spare(vd));
778
779 vp_abd = abd_alloc_linear(sizeof (vdev_phys_t), B_TRUE);
780 vp = abd_to_buf(vp_abd);
781
782retry:
783 for (int l = 0; l < VDEV_LABELS; l++) {
784 nvlist_t *label = NULL;
785
786 zio = zio_root(spa, NULL, NULL, flags);
787
788 vdev_label_read(zio, vd, l, vp_abd,
789 offsetof(vdev_label_t, vl_vdev_phys),
790 sizeof (vdev_phys_t), NULL, NULL, flags);
791
792 if (zio_wait(zio) == 0 &&
793 nvlist_unpack(vp->vp_nvlist, sizeof (vp->vp_nvlist),
794 &label, 0) == 0) {
795 /*
796 * Auxiliary vdevs won't have txg values in their
797 * labels and newly added vdevs may not have been
798 * completely initialized so just return the
799 * configuration from the first valid label we
800 * encounter.
801 */
802 error = nvlist_lookup_uint64(label,
803 ZPOOL_CONFIG_POOL_TXG, &label_txg);
804 if ((error || label_txg == 0) && !config) {
805 config = label;
806 break;
807 } else if (label_txg <= txg && label_txg > best_txg) {
808 best_txg = label_txg;
809 nvlist_free(config);

Callers 4

vdev_validateFunction · 0.85
vdev_validate_auxFunction · 0.85
vdev_inuseFunction · 0.85
vdev_uberblock_loadFunction · 0.85

Calls 14

spa_config_heldFunction · 0.85
vdev_readableFunction · 0.85
abd_alloc_linearFunction · 0.85
abd_to_bufFunction · 0.85
zio_rootFunction · 0.85
vdev_label_readFunction · 0.85
zio_waitFunction · 0.85
nvlist_lookup_uint64Function · 0.85
fnvlist_dupFunction · 0.85
vdev_dbgmsgFunction · 0.85
abd_freeFunction · 0.85

Tested by

no test coverage detected