Author: delphij
Date: Fri Jul  5 03:44:08 2013
New Revision: 252756
URL: http://svnweb.freebsd.org/changeset/base/252756

Log:
  MFC r251633: illumos #3744 zfs shouldn't ignore errors unmounting
  snapshots
  
  Propagate errors from zfs_unmount_snap() up to its callers wherever
  feasible.
  
  Submitted by: will
  Reviewed by:  Matthew Ahrens <[email protected]>,
                Christopher Siden <[email protected]>
  Sponsored by: Spectra Logic

Modified:
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h
  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/dsl_userhold.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c      
Fri Jul  5 03:38:53 2013        (r252755)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c      
Fri Jul  5 03:44:08 2013        (r252756)
@@ -433,7 +433,7 @@ dsl_dataset_user_release_tmp(dsl_pool_t 
                dsl_dataset_name(ds, name);
                dsl_dataset_rele(ds, FTAG);
                dsl_pool_config_exit(dp, FTAG);
-               zfs_unmount_snap(name);
+               (void) zfs_unmount_snap(name);
        } else {
                dsl_pool_config_exit(dp, FTAG);
        }

Modified: 
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h     
Fri Jul  5 03:38:53 2013        (r252755)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h     
Fri Jul  5 03:44:08 2013        (r252756)
@@ -360,7 +360,7 @@ extern int zfs_secpolicy_rename_perms(co
     const char *to, cred_t *cr);
 extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
 extern int zfs_busy(void);
-extern void zfs_unmount_snap(const char *);
+extern int zfs_unmount_snap(const char *);
 extern void zfs_destroy_unmount_origin(const char *);
 
 /*

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 Jul 
 5 03:38:53 2013        (r252755)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Fri Jul 
 5 03:44:08 2013        (r252756)
@@ -3405,28 +3405,31 @@ zfs_ioc_log_history(const char *unused, 
  *
  * This function is best-effort.  Callers must deal gracefully if it
  * remains mounted (or is remounted after this call).
+ *
+ * Returns 0 if the argument is not a snapshot, or it is not currently a
+ * filesystem, or we were able to unmount it.  Returns error code otherwise.
  */
-void
+int
 zfs_unmount_snap(const char *snapname)
 {
        vfs_t *vfsp;
        zfsvfs_t *zfsvfs;
+       int err;
 
        if (strchr(snapname, '@') == NULL)
-               return;
+               return (0);
 
        vfsp = zfs_get_vfs(snapname);
        if (vfsp == NULL)
-               return;
+               return (0);
 
        zfsvfs = vfsp->vfs_data;
        ASSERT(!dsl_pool_config_held(dmu_objset_pool(zfsvfs->z_os)));
 
-       if (vn_vfswlock(vfsp->vfs_vnodecovered) != 0) {
-               VFS_RELE(vfsp);
-               return;
-       }
+       err = vn_vfswlock(vfsp->vfs_vnodecovered);
        VFS_RELE(vfsp);
+       if (err != 0)
+               return (SET_ERROR(err));
 
        /*
         * Always force the unmount for snapshots.
@@ -3436,17 +3439,17 @@ zfs_unmount_snap(const char *snapname)
        (void) dounmount(vfsp, MS_FORCE, kcred);
 #else
        mtx_lock(&Giant);       /* dounmount() */
-       dounmount(vfsp, MS_FORCE, curthread);
+       (void) dounmount(vfsp, MS_FORCE, curthread);
        mtx_unlock(&Giant);     /* dounmount() */
 #endif
+       return (0);
 }
 
 /* ARGSUSED */
 static int
 zfs_unmount_snap_cb(const char *snapname, void *arg)
 {
-       zfs_unmount_snap(snapname);
-       return (0);
+       return (zfs_unmount_snap(snapname));
 }
 
 /*
@@ -3469,7 +3472,7 @@ zfs_destroy_unmount_origin(const char *f
                char originname[MAXNAMELEN];
                dsl_dataset_name(ds->ds_prev, originname);
                dmu_objset_rele(os, FTAG);
-               zfs_unmount_snap(originname);
+               (void) zfs_unmount_snap(originname);
        } else {
                dmu_objset_rele(os, FTAG);
        }
@@ -3487,7 +3490,7 @@ zfs_destroy_unmount_origin(const char *f
 static int
 zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
 {
-       int poollen;
+       int error, poollen;
        nvlist_t *snaps;
        nvpair_t *pair;
        boolean_t defer;
@@ -3508,7 +3511,9 @@ zfs_ioc_destroy_snaps(const char *poolna
                    (name[poollen] != '/' && name[poollen] != '@'))
                        return (SET_ERROR(EXDEV));
 
-               zfs_unmount_snap(name);
+               error = zfs_unmount_snap(name);
+               if (error != 0)
+                       return (error);
                (void) zvol_remove_minor(name);
        }
 
@@ -3527,8 +3532,12 @@ static int
 zfs_ioc_destroy(zfs_cmd_t *zc)
 {
        int err;
-       if (strchr(zc->zc_name, '@') && zc->zc_objset_type == DMU_OST_ZFS)
-               zfs_unmount_snap(zc->zc_name);
+
+       if (zc->zc_objset_type == DMU_OST_ZFS) {
+               err = zfs_unmount_snap(zc->zc_name);
+               if (err != 0)
+                       return (err);
+       }
 
        if (strchr(zc->zc_name, '@'))
                err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
@@ -3574,8 +3583,7 @@ recursive_unmount(const char *fsname, vo
        char fullname[MAXNAMELEN];
 
        (void) snprintf(fullname, sizeof (fullname), "%s@%s", fsname, snapname);
-       zfs_unmount_snap(fullname);
-       return (0);
+       return (zfs_unmount_snap(fullname));
 }
 
 /*
@@ -5071,14 +5079,18 @@ static int
 zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
 {
        nvpair_t *pair;
+       int err;
 
        /*
         * The release may cause the snapshot to be destroyed; make sure it
         * is not mounted.
         */
        for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
-           pair = nvlist_next_nvpair(holds, pair))
-               zfs_unmount_snap(nvpair_name(pair));
+           pair = nvlist_next_nvpair(holds, pair)) {
+               err = zfs_unmount_snap(nvpair_name(pair));
+               if (err != 0)
+                       return (err);
+       }
 
        return (dsl_dataset_user_release(holds, errlist));
 }
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "[email protected]"

Reply via email to