Date: Tue, 1 Jun 2010 08:43:46 +0000 (UTC) From: Martin Matuska <mm@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r208689 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs Message-ID: <201006010843.o518hkZi076208@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mm Date: Tue Jun 1 08:43:46 2010 New Revision: 208689 URL: http://svn.freebsd.org/changeset/base/208689 Log: 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 Approved by: pjd, delphij (mentor) Obtained from: OpenSolaris (Bug ID 6798298) MFC after: 3 days Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Tue Jun 1 05:32:59 2010 (r208688) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Tue Jun 1 08:43:46 2010 (r208689) @@ -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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006010843.o518hkZi076208>