* Sync the uberblock and any changes to the vdev configuration. * * The order of operations is carefully crafted to ensure that * if the system panics or loses power at any time, the state on disk * is still transactionally consistent. The in-line comments below * describe the failure semantics at each stage. * * Moreover, vdev_config_sync() is designed to be idempotent: if it fails * at
| 1859 | * at any time, you can just call it again, and it will resume its work. |
| 1860 | */ |
| 1861 | int |
| 1862 | vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg) |
| 1863 | { |
| 1864 | spa_t *spa = svd[0]->vdev_spa; |
| 1865 | uberblock_t *ub = &spa->spa_uberblock; |
| 1866 | int error = 0; |
| 1867 | int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; |
| 1868 | |
| 1869 | ASSERT(svdcount != 0); |
| 1870 | retry: |
| 1871 | /* |
| 1872 | * Normally, we don't want to try too hard to write every label and |
| 1873 | * uberblock. If there is a flaky disk, we don't want the rest of the |
| 1874 | * sync process to block while we retry. But if we can't write a |
| 1875 | * single label out, we should retry with ZIO_FLAG_TRYHARD before |
| 1876 | * bailing out and declaring the pool faulted. |
| 1877 | */ |
| 1878 | if (error != 0) { |
| 1879 | if ((flags & ZIO_FLAG_TRYHARD) != 0) |
| 1880 | return (error); |
| 1881 | flags |= ZIO_FLAG_TRYHARD; |
| 1882 | } |
| 1883 | |
| 1884 | ASSERT(ub->ub_txg <= txg); |
| 1885 | |
| 1886 | /* |
| 1887 | * If this isn't a resync due to I/O errors, |
| 1888 | * and nothing changed in this transaction group, |
| 1889 | * and the vdev configuration hasn't changed, |
| 1890 | * then there's nothing to do. |
| 1891 | */ |
| 1892 | if (ub->ub_txg < txg) { |
| 1893 | boolean_t changed = uberblock_update(ub, spa->spa_root_vdev, |
| 1894 | txg, spa->spa_mmp.mmp_delay); |
| 1895 | |
| 1896 | if (!changed && list_is_empty(&spa->spa_config_dirty_list)) |
| 1897 | return (0); |
| 1898 | } |
| 1899 | |
| 1900 | if (txg > spa_freeze_txg(spa)) |
| 1901 | return (0); |
| 1902 | |
| 1903 | ASSERT(txg <= spa->spa_final_txg); |
| 1904 | |
| 1905 | /* |
| 1906 | * Flush the write cache of every disk that's been written to |
| 1907 | * in this transaction group. This ensures that all blocks |
| 1908 | * written in this txg will be committed to stable storage |
| 1909 | * before any uberblock that references them. |
| 1910 | */ |
| 1911 | zio_t *zio = zio_root(spa, NULL, NULL, flags); |
| 1912 | |
| 1913 | for (vdev_t *vd = |
| 1914 | txg_list_head(&spa->spa_vdev_txg_list, TXG_CLEAN(txg)); vd != NULL; |
| 1915 | vd = txg_list_next(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg))) |
| 1916 | zio_flush(zio, vd); |
| 1917 | |
| 1918 | (void) zio_wait(zio); |
no test coverage detected