summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2016-12-24 14:12:52 +0000
committeravg <avg@FreeBSD.org>2016-12-24 14:12:52 +0000
commit9e4a9f6c96f4b3a1454b0946b5b44e371d67ca0b (patch)
treee85c47231e0b3dadd32d8415d218db20a92d4248 /sys/cddl
parent29cf69d0fdeacdd9809208786e6ed1ab3c4f0ecb (diff)
downloadFreeBSD-src-9e4a9f6c96f4b3a1454b0946b5b44e371d67ca0b.zip
FreeBSD-src-9e4a9f6c96f4b3a1454b0946b5b44e371d67ca0b.tar.gz
MFC r309097: MFV r308987: 7180 potential race between
zfs_suspend_fs+zfs_resume_fs and zfs_ioc_rename
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c14
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c13
3 files changed, 18 insertions, 11 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
index df5ce05..bcf22cd 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
@@ -142,7 +142,7 @@ extern uint_t zfs_fsyncer_key;
extern int zfs_super_owner;
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/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index 52b9c83..0e2ba77 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -3788,12 +3788,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;
}
#ifdef illumos
@@ -4444,8 +4447,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
@@ -4453,7 +4458,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;
#ifdef illumos
VFS_RELE(zfsvfs->z_vfs);
@@ -4999,11 +5004,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/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index fbaa324..ffc5f57 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -2225,7 +2225,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;
@@ -2234,14 +2234,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)
OpenPOWER on IntegriCloud