svn commit: r197133 -
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Pawel Jakub Dawidek
pjd at FreeBSD.org
Sat Sep 12 19:53:31 UTC 2009
Author: pjd
Date: Sat Sep 12 19:53:31 2009
New Revision: 197133
URL: http://svn.freebsd.org/changeset/base/197133
Log:
- Protect reclaim with z_teardown_inactive_lock.
- Be prepared for dbuf to disappear in zfs_reclaim_complete() and check if
z_dbuf field is NULL - this might happen in case of rollback or forced
unmount between zfs_freebsd_reclaim() and zfs_reclaim_complete().
- On forced unmount wait for all znodes to be destroyed - destruction can be
done asynchronously via zfs_reclaim_complete().
MFC after: 1 week
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.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 Sat Sep 12 19:45:55 2009 (r197132)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Sat Sep 12 19:53:31 2009 (r197133)
@@ -947,6 +947,18 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolea
zfsvfs->z_unmounted = B_TRUE;
rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
rw_exit(&zfsvfs->z_teardown_inactive_lock);
+
+#ifdef __FreeBSD__
+ /*
+ * Some znodes might not be fully reclaimed, wait for them.
+ */
+ mutex_enter(&zfsvfs->z_znodes_lock);
+ while (list_head(&zfsvfs->z_all_znodes) != NULL) {
+ msleep(zfsvfs, &zfsvfs->z_znodes_lock, 0,
+ "zteardown", 0);
+ }
+ mutex_exit(&zfsvfs->z_znodes_lock);
+#endif
}
/*
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sat Sep 12 19:45:55 2009 (r197132)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sat Sep 12 19:53:31 2009 (r197133)
@@ -4343,11 +4343,20 @@ zfs_reclaim_complete(void *arg, int pend
znode_t *zp = arg;
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
- ZFS_LOG(1, "zp=%p", zp);
- ZFS_OBJ_HOLD_ENTER(zfsvfs, zp->z_id);
- zfs_znode_dmu_fini(zp);
- ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id);
+ rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER);
+ if (zp->z_dbuf != NULL) {
+ ZFS_OBJ_HOLD_ENTER(zfsvfs, zp->z_id);
+ zfs_znode_dmu_fini(zp);
+ ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id);
+ }
zfs_znode_free(zp);
+ rw_exit(&zfsvfs->z_teardown_inactive_lock);
+ /*
+ * If the file system is being unmounted, there is a process waiting
+ * for us, wake it up.
+ */
+ if (zfsvfs->z_unmounted)
+ wakeup_one(zfsvfs);
}
static int
@@ -4359,6 +4368,9 @@ zfs_freebsd_reclaim(ap)
{
vnode_t *vp = ap->a_vp;
znode_t *zp = VTOZ(vp);
+ zfsvfs_t *zfsvfs = zp->z_zfsvfs;
+
+ rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER);
ASSERT(zp != NULL);
@@ -4377,7 +4389,6 @@ zfs_freebsd_reclaim(ap)
else if (zp->z_dbuf == NULL)
zfs_znode_free(zp);
else /* if (!zp->z_unlinked && zp->z_dbuf != NULL) */ {
- zfsvfs_t *zfsvfs = zp->z_zfsvfs;
int locked;
locked = MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id)) ? 2 :
@@ -4400,6 +4411,7 @@ zfs_freebsd_reclaim(ap)
vp->v_data = NULL;
ASSERT(vp->v_holdcnt >= 1);
VI_UNLOCK(vp);
+ rw_exit(&zfsvfs->z_teardown_inactive_lock);
return (0);
}
More information about the svn-src-head
mailing list