Author: avg
Date: Fri Aug 23 13:29:53 2013
New Revision: 254696
URL: http://svnweb.freebsd.org/changeset/base/254696

Log:
  MFC r253606: zfs module: perform cleanup during shutdown in addition to
  module unload

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

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Fri Aug 
23 13:27:27 2013        (r254695)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Fri Aug 
23 13:29:53 2013        (r254696)
@@ -6194,54 +6194,96 @@ _info(struct modinfo *modinfop)
 }
 #endif /* sun */
 
-static int
-zfs_modevent(module_t mod, int type, void *unused __unused)
+static int zfs__init(void);
+static int zfs__fini(void);
+static void zfs_shutdown(void *, int);
+
+static eventhandler_tag zfs_shutdown_event_tag;
+
+int
+zfs__init(void)
 {
-       int error = 0;
 
-       switch (type) {
-       case MOD_LOAD:
-               zfs_root_token = root_mount_hold("ZFS");
+       zfs_root_token = root_mount_hold("ZFS");
 
-               mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
+       mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
 
-               spa_init(FREAD | FWRITE);
-               zfs_init();
-               zvol_init();
-               zfs_ioctl_init();
+       spa_init(FREAD | FWRITE);
+       zfs_init();
+       zvol_init();
+       zfs_ioctl_init();
 
-               tsd_create(&zfs_fsyncer_key, NULL);
-               tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
-               tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
+       tsd_create(&zfs_fsyncer_key, NULL);
+       tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
+       tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
 
-               printf("ZFS storage pool version: features support (" 
SPA_VERSION_STRING ")\n");
-               root_mount_rel(zfs_root_token);
+       printf("ZFS storage pool version: features support (" 
SPA_VERSION_STRING ")\n");
+       root_mount_rel(zfs_root_token);
 
-               zfsdev_init();
-               break;
-       case MOD_UNLOAD:
-               if (spa_busy() || zfs_busy() || zvol_busy() ||
-                   zio_injection_enabled) {
-                       error = EBUSY;
-                       break;
-               }
-
-               zfsdev_fini();
-               zvol_fini();
-               zfs_fini();
-               spa_fini();
-
-               tsd_destroy(&zfs_fsyncer_key);
-               tsd_destroy(&rrw_tsd_key);
-               tsd_destroy(&zfs_allow_log_key);
+       zfsdev_init();
 
-               mutex_destroy(&zfs_share_lock);
-               break;
+       return (0);
+}
+
+int
+zfs__fini(void)
+{
+       if (spa_busy() || zfs_busy() || zvol_busy() ||
+           zio_injection_enabled) {
+               return (EBUSY);
+       }
+
+       zfsdev_fini();
+       zvol_fini();
+       zfs_fini();
+       spa_fini();
+
+       tsd_destroy(&zfs_fsyncer_key);
+       tsd_destroy(&rrw_tsd_key);
+       tsd_destroy(&zfs_allow_log_key);
+
+       mutex_destroy(&zfs_share_lock);
+
+       return (0);
+}
+
+static void
+zfs_shutdown(void *arg __unused, int howto __unused)
+{
+
+       /*
+        * ZFS fini routines can not properly work in a panic-ed system.
+        */
+       if (panicstr == NULL)
+               (void)zfs__fini();
+}
+
+
+static int
+zfs_modevent(module_t mod, int type, void *unused __unused)
+{
+       int err;
+
+       switch (type) {
+       case MOD_LOAD:
+               err = zfs__init();
+               if (err == 0)
+                       zfs_shutdown_event_tag = EVENTHANDLER_REGISTER(
+                           shutdown_post_sync, zfs_shutdown, NULL,
+                           SHUTDOWN_PRI_FIRST);
+               return (err);
+       case MOD_UNLOAD:
+               err = zfs__fini();
+               if (err == 0 && zfs_shutdown_event_tag != NULL)
+                       EVENTHANDLER_DEREGISTER(shutdown_post_sync,
+                           zfs_shutdown_event_tag);
+               return (err);
+       case MOD_SHUTDOWN:
+               return (0);
        default:
-               error = EOPNOTSUPP;
                break;
        }
-       return (error);
+       return (EOPNOTSUPP);
 }
 
 static moduledata_t zfs_mod = {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to