diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-11-22 12:56:16 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-11-22 12:56:16 +0000 |
| commit | dec418ad77ca1ad8b6560e627d4f4d4cee27ab5c (patch) | |
| tree | 8b010779fbe156ed1462f203170b948386ec6023 /usr/src/uts/common | |
| parent | 0e094404f4a199a440ac665b3442f89891352798 (diff) | |
| parent | 90f2c094b3822f4825f21cef2c2faf7d03b55139 (diff) | |
| download | illumos-joyent-dec418ad77ca1ad8b6560e627d4f4d4cee27ab5c.tar.gz | |
[illumos-gate merge]
commit 90f2c094b3822f4825f21cef2c2faf7d03b55139
7181 race between zfs_mount and zfs_ioc_rollback
commit 3faa67c4f6f8f33a78fe84ef48445aeb0ce858d3
7566 Add kernel environment variables under smbios.system.
commit c079fa4d202eff15e318131c52755d214ffa2da7
6428 set canmount=off on unmounted filesystem tries to unmount children
commit bfaed0b91e57062c38bc16b4f89db3c8f0052a9b
7199 dsl_dataset_rollback_sync may try to free already free blocks
7200 no blocks must be born in a txg after a snaphot is created
commit edb901aab9c738b5eb15aa55933e82b0f2f9d9a2
7386 zfs get does not work properly with bookmarks
commit 690041b9caf801816f2d0bac90bc7cecefb73523
7180 potential race between zfs_suspend_fs+zfs_resume_fs and zfs_ioc_rename
commit e5b103bba9ae456b34ffc1e123d7e81d4584a945
7596 iwn: Firmware update for 6205 (Taylor Peak)
Diffstat (limited to 'usr/src/uts/common')
| -rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_dataset.c | 62 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_pool.c | 14 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/sys/dsl_dataset.h | 1 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_ioctl.c | 14 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vfsops.c | 27 | ||||
| -rw-r--r-- | usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucode | bin | 444128 -> 0 bytes | |||
| -rw-r--r-- | usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucode | bin | 0 -> 677296 bytes | |||
| -rw-r--r-- | usr/src/uts/common/io/iwn/if_iwn.c | 2 |
9 files changed, 85 insertions, 37 deletions
diff --git a/usr/src/uts/common/fs/zfs/dsl_dataset.c b/usr/src/uts/common/fs/zfs/dsl_dataset.c index 74409fecaa..bac325b3a1 100644 --- a/usr/src/uts/common/fs/zfs/dsl_dataset.c +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c @@ -81,6 +81,8 @@ extern inline dsl_dataset_phys_t *dsl_dataset_phys(dsl_dataset_t *ds); extern int spa_asize_inflation; +static zil_header_t zero_zil; + /* * Figure out how much of this delta should be propogated to the dsl_dir * layer. If there's a refreservation, that space has already been @@ -125,6 +127,7 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx) return; } + ASSERT3U(bp->blk_birth, >, dsl_dataset_phys(ds)->ds_prev_snap_txg); dmu_buf_will_dirty(ds->ds_dbuf, tx); mutex_enter(&ds->ds_lock); delta = parent_delta(ds, used); @@ -914,8 +917,20 @@ dsl_dataset_zero_zil(dsl_dataset_t *ds, dmu_tx_t *tx) objset_t *os; VERIFY0(dmu_objset_from_ds(ds, &os)); - bzero(&os->os_zil_header, sizeof (os->os_zil_header)); - dsl_dataset_dirty(ds, tx); + if (bcmp(&os->os_zil_header, &zero_zil, sizeof (zero_zil)) != 0) { + dsl_pool_t *dp = ds->ds_dir->dd_pool; + zio_t *zio; + + bzero(&os->os_zil_header, sizeof (os->os_zil_header)); + + zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); + dsl_dataset_sync(ds, zio, tx); + VERIFY0(zio_wait(zio)); + + /* dsl_dataset_sync_done will drop this reference. */ + dmu_buf_add_ref(ds->ds_dbuf, ds); + dsl_dataset_sync_done(ds, tx); + } } uint64_t @@ -1055,8 +1070,10 @@ dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx) if (dsl_dataset_phys(ds)->ds_next_snap_obj != 0) panic("dirtying snapshot!"); - dp = ds->ds_dir->dd_pool; + /* Must not dirty a dataset in the same txg where it got snapshotted. */ + ASSERT3U(tx->tx_txg, >, dsl_dataset_phys(ds)->ds_prev_snap_txg); + dp = ds->ds_dir->dd_pool; if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg)) { /* up the hold count until we can be written out */ dmu_buf_add_ref(ds->ds_dbuf, ds); @@ -1311,8 +1328,6 @@ void dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, dmu_tx_t *tx) { - static zil_header_t zero_zil; - dsl_pool_t *dp = ds->ds_dir->dd_pool; dmu_buf_t *dbuf; dsl_dataset_phys_t *dsphys; @@ -1331,6 +1346,10 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, bcmp(&os->os_phys->os_zil_header, &zero_zil, sizeof (zero_zil)) == 0); + /* Should not snapshot a dirty dataset. */ + ASSERT(!txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets, + ds, tx->tx_txg)); + dsl_fs_ss_count_adjust(ds->ds_dir, 1, DD_FIELD_SNAPSHOT_COUNT, tx); /* @@ -1677,6 +1696,27 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) } } +static int +deadlist_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) +{ + dsl_deadlist_t *dl = arg; + dsl_deadlist_insert(dl, bp, tx); + return (0); +} + +void +dsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx) +{ + objset_t *os = ds->ds_objset; + + bplist_iterate(&ds->ds_pending_deadlist, + deadlist_enqueue_cb, &ds->ds_deadlist, tx); + + ASSERT(!dmu_objset_is_dirty(os, dmu_tx_get_txg(tx))); + + dmu_buf_rele(ds->ds_dbuf, ds); +} + static void get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv) { @@ -2176,6 +2216,18 @@ dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx) return (SET_ERROR(EINVAL)); } + /* + * No rollback to a snapshot created in the current txg, because + * the rollback may dirty the dataset and create blocks that are + * not reachable from the rootbp while having a birth txg that + * falls into the snapshot's range. + */ + if (dmu_tx_is_syncing(tx) && + dsl_dataset_phys(ds)->ds_prev_snap_txg >= tx->tx_txg) { + dsl_dataset_rele(ds, FTAG); + return (SET_ERROR(EAGAIN)); + } + /* must not have any bookmarks after the most recent snapshot */ nvlist_t *proprequest = fnvlist_alloc(); fnvlist_add_boolean(proprequest, zfs_prop_to_name(ZFS_PROP_CREATETXG)); diff --git a/usr/src/uts/common/fs/zfs/dsl_pool.c b/usr/src/uts/common/fs/zfs/dsl_pool.c index 995fc6aa48..0d44ba6ac6 100644 --- a/usr/src/uts/common/fs/zfs/dsl_pool.c +++ b/usr/src/uts/common/fs/zfs/dsl_pool.c @@ -425,14 +425,6 @@ dsl_pool_mos_diduse_space(dsl_pool_t *dp, mutex_exit(&dp->dp_lock); } -static int -deadlist_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) -{ - dsl_deadlist_t *dl = arg; - dsl_deadlist_insert(dl, bp, tx); - return (0); -} - static void dsl_pool_sync_mos(dsl_pool_t *dp, dmu_tx_t *tx) { @@ -533,11 +525,7 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg) * - release hold from dsl_dataset_dirty() */ while ((ds = list_remove_head(&synced_datasets)) != NULL) { - objset_t *os = ds->ds_objset; - bplist_iterate(&ds->ds_pending_deadlist, - deadlist_enqueue_cb, &ds->ds_deadlist, tx); - ASSERT(!dmu_objset_is_dirty(os, txg)); - dmu_buf_rele(ds->ds_dbuf, ds); + dsl_dataset_sync_done(ds, tx); } while ((dd = txg_list_remove(&dp->dp_dirty_dirs, txg)) != NULL) { dsl_dir_sync(dd, tx); diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h index 18466bb405..22c67b48a9 100644 --- a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h +++ b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h @@ -274,6 +274,7 @@ boolean_t dsl_dataset_modified_since_snap(dsl_dataset_t *ds, dsl_dataset_t *snap); void dsl_dataset_sync(dsl_dataset_t *os, zio_t *zio, dmu_tx_t *tx); +void dsl_dataset_sync_done(dsl_dataset_t *os, dmu_tx_t *tx); void dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx); diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h index b382d27bdf..3278171372 100644 --- a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h +++ b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h @@ -137,7 +137,7 @@ typedef struct zfid_long { extern uint_t zfs_fsyncer_key; extern int zfs_suspend_fs(zfsvfs_t *zfsvfs); -extern int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname); +extern int zfs_resume_fs(zfsvfs_t *zfsvfs, struct dsl_dataset *ds); extern int zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, const char *domain, uint64_t rid, uint64_t *valuep); extern int zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c index 1948aa443b..823822e44c 100644 --- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c @@ -3683,12 +3683,15 @@ zfs_ioc_rollback(const char *fsname, nvlist_t *args, nvlist_t *outnvl) int error; if (getzfsvfs(fsname, &zfsvfs) == 0) { + dsl_dataset_t *ds; + + ds = dmu_objset_ds(zfsvfs->z_os); error = zfs_suspend_fs(zfsvfs); if (error == 0) { int resume_err; error = dsl_dataset_rollback(fsname, zfsvfs, outnvl); - resume_err = zfs_resume_fs(zfsvfs, fsname); + resume_err = zfs_resume_fs(zfsvfs, ds); error = error ? error : resume_err; } VFS_RELE(zfsvfs->z_vfs); @@ -4313,8 +4316,10 @@ zfs_ioc_recv(zfs_cmd_t *zc) if (getzfsvfs(tofs, &zfsvfs) == 0) { /* online recv */ + dsl_dataset_t *ds; int end_err; + ds = dmu_objset_ds(zfsvfs->z_os); error = zfs_suspend_fs(zfsvfs); /* * If the suspend fails, then the recv_end will @@ -4322,7 +4327,7 @@ zfs_ioc_recv(zfs_cmd_t *zc) */ end_err = dmu_recv_end(&drc, zfsvfs); if (error == 0) - error = zfs_resume_fs(zfsvfs, tofs); + error = zfs_resume_fs(zfsvfs, ds); error = error ? error : end_err; VFS_RELE(zfsvfs->z_vfs); } else { @@ -4846,11 +4851,14 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) * objset needs to be closed & reopened (to grow the * objset_phys_t). Suspend/resume the fs will do that. */ + dsl_dataset_t *ds; + + ds = dmu_objset_ds(zfsvfs->z_os); error = zfs_suspend_fs(zfsvfs); if (error == 0) { dmu_objset_refresh_ownership(zfsvfs->z_os, zfsvfs); - error = zfs_resume_fs(zfsvfs, zc->zc_name); + error = zfs_resume_fs(zfsvfs, ds); } } if (error == 0) diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c index f069e3553e..9e0a8c0ed8 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c @@ -1020,13 +1020,6 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) if (error) return (error); - /* - * Set the objset user_ptr to track its zfsvfs. - */ - mutex_enter(&zfsvfs->z_os->os_user_ptr_lock); - dmu_objset_set_user(zfsvfs->z_os, zfsvfs); - mutex_exit(&zfsvfs->z_os->os_user_ptr_lock); - zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data); /* @@ -1087,6 +1080,13 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */ } + /* + * Set the objset user_ptr to track its zfsvfs. + */ + mutex_enter(&zfsvfs->z_os->os_user_ptr_lock); + dmu_objset_set_user(zfsvfs->z_os, zfsvfs); + mutex_exit(&zfsvfs->z_os->os_user_ptr_lock); + return (0); } @@ -2032,7 +2032,7 @@ zfs_suspend_fs(zfsvfs_t *zfsvfs) * zfsvfs, held, and long held on entry. */ int -zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) +zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds) { int err; znode_t *zp; @@ -2041,14 +2041,13 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock)); /* - * We already own this, so just hold and rele it to update the - * objset_t, as the one we had before may have been evicted. + * We already own this, so just update the objset_t, as the one we + * had before may have been evicted. */ objset_t *os; - VERIFY0(dmu_objset_hold(osname, zfsvfs, &os)); - VERIFY3P(os->os_dsl_dataset->ds_owner, ==, zfsvfs); - VERIFY(dsl_dataset_long_held(os->os_dsl_dataset)); - dmu_objset_rele(os, zfsvfs); + VERIFY3P(ds->ds_owner, ==, zfsvfs); + VERIFY(dsl_dataset_long_held(ds)); + VERIFY0(dmu_objset_from_ds(ds, &os)); err = zfsvfs_init(zfsvfs, os); if (err != 0) diff --git a/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucode b/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucode Binary files differdeleted file mode 100644 index 24f7d146d0..0000000000 --- a/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucode +++ /dev/null diff --git a/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucode b/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucode Binary files differnew file mode 100644 index 0000000000..a1f2454df7 --- /dev/null +++ b/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucode diff --git a/usr/src/uts/common/io/iwn/if_iwn.c b/usr/src/uts/common/io/iwn/if_iwn.c index a4334cc19d..fc60627899 100644 --- a/usr/src/uts/common/io/iwn/if_iwn.c +++ b/usr/src/uts/common/io/iwn/if_iwn.c @@ -1321,7 +1321,7 @@ iwn5000_attach(struct iwn_softc *sc, uint16_t pid) ops->config_bt_coex = iwn_config_bt_coex_adv1; } else - sc->fwname = "iwlwifi-6000g2a-5.ucode"; + sc->fwname = "iwlwifi-6000g2a-6.ucode"; iwn_kstat_create(sc, "temp_offset", sizeof (struct iwn_ks_toff_6000), |
