MFV r251622:
ZFS shouldn't ignore errors unmounting snapshots Illumos ZFS issues: 3744 zfs shouldn't ignore errors unmounting snapshots MFC after: 2 weeks
This commit is contained in:
commit
3f3a9cac29
@ -433,7 +433,7 @@ dsl_dataset_user_release_tmp(dsl_pool_t *dp, uint64_t dsobj, const char *htag)
|
||||
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);
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ extern int zfs_secpolicy_rename_perms(const char *from,
|
||||
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 *);
|
||||
|
||||
/*
|
||||
|
@ -3405,28 +3405,31 @@ zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
*
|
||||
* 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 *fsname)
|
||||
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 *fsname)
|
||||
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 *poolname, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
(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, void *arg)
|
||||
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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user