Author: avg
Date: Sat Dec 24 14:13:21 2016
New Revision: 310510
URL: https://svnweb.freebsd.org/changeset/base/310510

Log:
  MFC r309097: MFV r308987: 7180 potential race between
  zfs_suspend_fs+zfs_resume_fs and zfs_ioc_rename

Modified:
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
Directory Properties:
  stable/10/   (props changed)

Modified: 
stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h   
Sat Dec 24 14:12:52 2016        (r310509)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h   
Sat Dec 24 14:13:21 2016        (r310510)
@@ -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,

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c        
Sat Dec 24 14:12:52 2016        (r310509)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c        
Sat Dec 24 14:13:21 2016        (r310510)
@@ -3788,12 +3788,15 @@ zfs_ioc_rollback(const char *fsname, nvl
        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)

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c       
Sat Dec 24 14:12:52 2016        (r310509)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c       
Sat Dec 24 14:13:21 2016        (r310510)
@@ -2226,7 +2226,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;
@@ -2235,14 +2235,13 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const ch
        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)
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to