svn commit: r197459 - in head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys

Pawel Jakub Dawidek pjd at FreeBSD.org
Thu Sep 24 15:56:26 UTC 2009


Author: pjd
Date: Thu Sep 24 15:56:26 2009
New Revision: 197459
URL: http://svn.freebsd.org/changeset/base/197459

Log:
  Before calling vflush(FORCECLOSE) mark file system as unmounted so the
  following vnops will fail. This is very important, because without this change
  vnode could be reclaimed at any point, even if we increased usecount. The only
  way to ensure that vnode won't be reclaimed was to lock it, which would be very
  hard to do in ZFS without changing a lot of code. With this change simply
  increasing usecount is enough to be sure vnode won't be reclaimed from under
  us. To be precise it can still be reclaimed but we won't be able to see it,
  because every try to enter ZFS through VFS will result in EIO.
  
  The only function that cannot return EIO, because it is needed for vflush() is
  zfs_root(). Introduce ZFS_ENTER_NOERROR() macro that only locks
  z_teardown_lock and never returns EIO.
  
  MFC after:	3 days

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Thu Sep 24 15:49:15 2009	(r197458)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Thu Sep 24 15:56:26 2009	(r197459)
@@ -255,6 +255,7 @@ VTOZ(vnode_t *vp)
 
 /*
  * ZFS_ENTER() is called on entry to each ZFS vnode and vfs operation.
+ * ZFS_ENTER_NOERROR() is called when we can't return EIO.
  * ZFS_EXIT() must be called before exitting the vop.
  * ZFS_VERIFY_ZP() verifies the znode is valid.
  */
@@ -267,6 +268,9 @@ VTOZ(vnode_t *vp)
 		} \
 	}
 
+#define	ZFS_ENTER_NOERROR(zfsvfs) \
+	rrw_enter(&(zfsvfs)->z_teardown_lock, RW_READER, FTAG)
+
 #define	ZFS_EXIT(zfsvfs) rrw_exit(&(zfsvfs)->z_teardown_lock, FTAG)
 
 #define	ZFS_VERIFY_ZP(zp) \

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	Thu Sep 24 15:49:15 2009	(r197458)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Thu Sep 24 15:56:26 2009	(r197459)
@@ -864,7 +864,7 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t
 	znode_t *rootzp;
 	int error;
 
-	ZFS_ENTER(zfsvfs);
+	ZFS_ENTER_NOERROR(zfsvfs);
 
 	error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
 	if (error == 0) {
@@ -1030,6 +1030,17 @@ zfs_umount(vfs_t *vfsp, int fflag)
 		ASSERT(zfsvfs->z_ctldir == NULL);
 	}
 
+	if (fflag & MS_FORCE) {
+		/*
+		 * Mark file system as unmounted before calling
+		 * vflush(FORCECLOSE). This way we ensure no future vnops
+		 * will be called and risk operating on DOOMED vnodes.
+		 */
+		rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
+		zfsvfs->z_unmounted = B_TRUE;
+		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
+	}
+
 	/*
 	 * Flush all the files.
 	 */


More information about the svn-src-head mailing list