svn commit: r208799 -
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Martin Matuska
mm at FreeBSD.org
Fri Jun 4 08:46:27 UTC 2010
Author: mm
Date: Fri Jun 4 08:46:26 2010
New Revision: 208799
URL: http://svn.freebsd.org/changeset/base/208799
Log:
MFC r208689:
Fix ZIL close when doing zfs rollback or zfs receive on a mounted dataset.
The fix is a partial import and merge of OpenSolaris onnv revisions
8227:f7d7be9b1f56. and 9292:e112194b5b73
Reviewed by: pjd, delphij (mentor)
Obtained from: OpenSolaris (Bug ID 6798298)
Approved by: re (kib)
Modified:
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
stable/8/sys/geom/sched/ (props changed)
Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Fri Jun 4 08:19:43 2010 (r208798)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Fri Jun 4 08:46:26 2010 (r208799)
@@ -499,6 +499,12 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t
dmu_objset_set_user(zfsvfs->z_os, zfsvfs);
mutex_exit(&zfsvfs->z_os->os->os_user_ptr_lock);
+ zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data);
+ if (zil_disable) {
+ zil_destroy(zfsvfs->z_log, B_FALSE);
+ zfsvfs->z_log = NULL;
+ }
+
/*
* If we are not mounting (ie: online recv), then we don't
* have to worry about replaying the log as we blocked all
@@ -512,21 +518,45 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t
* allow replays to succeed.
*/
readonly = zfsvfs->z_vfs->vfs_flag & VFS_RDONLY;
- zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY;
-
- /*
- * Parse and replay the intent log.
- */
- zil_replay(zfsvfs->z_os, zfsvfs, &zfsvfs->z_assign,
- zfs_replay_vector, zfs_unlinked_drain);
+ if (readonly != 0)
+ zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY;
+ else
+ zfs_unlinked_drain(zfsvfs);
- zfs_unlinked_drain(zfsvfs);
+ if (zfsvfs->z_log) {
+ /*
+ * Parse and replay the intent log.
+ *
+ * Because of ziltest, this must be done after
+ * zfs_unlinked_drain(). (Further note: ziltest
+ * doesn't use readonly mounts, where
+ * zfs_unlinked_drain() isn't called.) This is because
+ * ziltest causes spa_sync() to think it's committed,
+ * but actually it is not, so the intent log contains
+ * many txg's worth of changes.
+ *
+ * In particular, if object N is in the unlinked set in
+ * the last txg to actually sync, then it could be
+ * actually freed in a later txg and then reallocated
+ * in a yet later txg. This would write a "create
+ * object N" record to the intent log. Normally, this
+ * would be fine because the spa_sync() would have
+ * written out the fact that object N is free, before
+ * we could write the "create object N" intent log
+ * record.
+ *
+ * But when we are in ziltest mode, we advance the "open
+ * txg" without actually spa_sync()-ing the changes to
+ * disk. So we would see that object N is still
+ * allocated and in the unlinked set, and there is an
+ * intent log record saying to allocate it.
+ */
+ zil_replay(zfsvfs->z_os, zfsvfs, &zfsvfs->z_assign,
+ zfs_replay_vector, zfs_unlinked_drain);
+ }
zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */
}
- if (!zil_disable)
- zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data);
-
return (0);
}
More information about the svn-src-stable
mailing list