pass handle to do_unmount()

The same change has already been done for domount(). On macOS platform
we need to have access to zhp to handle devdisks and snapshots.
Also, symmetry is pleasing.

In addition, the code in zpool_disable_datasets which sorts the
mountpoints did not sort the related handle, which meant that the
mountpoint, and the handle that it is paired with, was lost.
You'd get a random handle with the mountpoint.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: John Kennedy <john.kennedy@delphix.com>
Signed-off-by: Jorgen Lundman <lundman@lundman.net>
Closes #12296
This commit is contained in:
Jorgen Lundman 2021-07-16 03:31:00 +09:00 committed by GitHub
parent d9f0f1582c
commit 41eba77061
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 41 deletions

View File

@ -243,7 +243,8 @@ extern proto_table_t proto_table[PROTO_END];
extern int do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, extern int do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts,
int flags); int flags);
extern int do_unmount(const char *mntpt, int flags); extern int do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags);
extern int zfs_mount_delegation_check(void);
extern int zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto); extern int zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto);
extern int zfs_unshare_proto(zfs_handle_t *, const char *, zfs_share_proto_t *); extern int zfs_unshare_proto(zfs_handle_t *, const char *, zfs_share_proto_t *);
extern int unshare_one(libzfs_handle_t *hdl, const char *name, extern int unshare_one(libzfs_handle_t *hdl, const char *name,

View File

@ -568,11 +568,11 @@ zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags,
* Unmount a single filesystem. * Unmount a single filesystem.
*/ */
static int static int
unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags) unmount_one(zfs_handle_t *zhp, const char *mountpoint, int flags)
{ {
int error; int error;
error = do_unmount(mountpoint, flags); error = do_unmount(zhp, mountpoint, flags);
if (error != 0) { if (error != 0) {
int libzfs_err; int libzfs_err;
@ -595,7 +595,7 @@ unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags)
default: default:
libzfs_err = EZFS_UMOUNTFAILED; libzfs_err = EZFS_UMOUNTFAILED;
} }
return (zfs_error_fmt(hdl, libzfs_err, return (zfs_error_fmt(zhp->zfs_hdl, libzfs_err,
dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
mountpoint)); mountpoint));
} }
@ -637,7 +637,7 @@ zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
} }
zfs_commit_all_shares(); zfs_commit_all_shares();
if (unmount_one(hdl, mntpt, flags) != 0) { if (unmount_one(zhp, mntpt, flags) != 0) {
free(mntpt); free(mntpt);
(void) zfs_shareall(zhp); (void) zfs_shareall(zhp);
zfs_commit_all_shares(); zfs_commit_all_shares();
@ -1503,13 +1503,18 @@ out:
return (ret); return (ret);
} }
struct sets_s {
char *mountpoint;
zfs_handle_t *dataset;
};
static int static int
mountpoint_compare(const void *a, const void *b) mountpoint_compare(const void *a, const void *b)
{ {
const char *mounta = *((char **)a); const struct sets_s *mounta = (struct sets_s *)a;
const char *mountb = *((char **)b); const struct sets_s *mountb = (struct sets_s *)b;
return (strcmp(mountb, mounta)); return (strcmp(mountb->mountpoint, mounta->mountpoint));
} }
/* /*
@ -1526,8 +1531,7 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
FILE *mnttab; FILE *mnttab;
struct mnttab entry; struct mnttab entry;
size_t namelen; size_t namelen;
char **mountpoints = NULL; struct sets_s *sets = NULL;
zfs_handle_t **datasets = NULL;
libzfs_handle_t *hdl = zhp->zpool_hdl; libzfs_handle_t *hdl = zhp->zpool_hdl;
int i; int i;
int ret = -1; int ret = -1;
@ -1562,35 +1566,27 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
*/ */
if (used == alloc) { if (used == alloc) {
if (alloc == 0) { if (alloc == 0) {
if ((mountpoints = zfs_alloc(hdl,
8 * sizeof (void *))) == NULL)
goto out;
if ((datasets = zfs_alloc(hdl, if ((sets = zfs_alloc(hdl,
8 * sizeof (void *))) == NULL) 8 * sizeof (struct sets_s))) == NULL)
goto out; goto out;
alloc = 8; alloc = 8;
} else { } else {
void *ptr; void *ptr;
if ((ptr = zfs_realloc(hdl, mountpoints, if ((ptr = zfs_realloc(hdl, sets,
alloc * sizeof (void *), alloc * sizeof (struct sets_s),
alloc * 2 * sizeof (void *))) == NULL) alloc * 2 * sizeof (struct sets_s)))
== NULL)
goto out; goto out;
mountpoints = ptr; sets = ptr;
if ((ptr = zfs_realloc(hdl, datasets,
alloc * sizeof (void *),
alloc * 2 * sizeof (void *))) == NULL)
goto out;
datasets = ptr;
alloc *= 2; alloc *= 2;
} }
} }
if ((mountpoints[used] = zfs_strdup(hdl, if ((sets[used].mountpoint = zfs_strdup(hdl,
entry.mnt_mountp)) == NULL) entry.mnt_mountp)) == NULL)
goto out; goto out;
@ -1599,7 +1595,8 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
* is only used to determine if we need to remove the underlying * is only used to determine if we need to remove the underlying
* mountpoint, so failure is not fatal. * mountpoint, so failure is not fatal.
*/ */
datasets[used] = make_dataset_handle(hdl, entry.mnt_special); sets[used].dataset = make_dataset_handle(hdl,
entry.mnt_special);
used++; used++;
} }
@ -1608,7 +1605,7 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
* At this point, we have the entire list of filesystems, so sort it by * At this point, we have the entire list of filesystems, so sort it by
* mountpoint. * mountpoint.
*/ */
qsort(mountpoints, used, sizeof (char *), mountpoint_compare); qsort(sets, used, sizeof (struct sets_s), mountpoint_compare);
/* /*
* Walk through and first unshare everything. * Walk through and first unshare everything.
@ -1617,9 +1614,9 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
zfs_share_proto_t *curr_proto; zfs_share_proto_t *curr_proto;
for (curr_proto = share_all_proto; *curr_proto != PROTO_END; for (curr_proto = share_all_proto; *curr_proto != PROTO_END;
curr_proto++) { curr_proto++) {
if (is_shared(mountpoints[i], *curr_proto) && if (is_shared(sets[i].mountpoint, *curr_proto) &&
unshare_one(hdl, mountpoints[i], unshare_one(hdl, sets[i].mountpoint,
mountpoints[i], *curr_proto) != 0) sets[i].mountpoint, *curr_proto) != 0)
goto out; goto out;
} }
} }
@ -1630,25 +1627,25 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
* appropriate. * appropriate.
*/ */
for (i = 0; i < used; i++) { for (i = 0; i < used; i++) {
if (unmount_one(hdl, mountpoints[i], flags) != 0) if (unmount_one(sets[i].dataset, sets[i].mountpoint,
flags) != 0)
goto out; goto out;
} }
for (i = 0; i < used; i++) { for (i = 0; i < used; i++) {
if (datasets[i]) if (sets[i].dataset)
remove_mountpoint(datasets[i]); remove_mountpoint(sets[i].dataset);
} }
ret = 0; ret = 0;
out: out:
(void) fclose(mnttab); (void) fclose(mnttab);
for (i = 0; i < used; i++) { for (i = 0; i < used; i++) {
if (datasets[i]) if (sets[i].dataset)
zfs_close(datasets[i]); zfs_close(sets[i].dataset);
free(mountpoints[i]); free(sets[i].mountpoint);
} }
free(datasets); free(sets);
free(mountpoints);
return (ret); return (ret);
} }

View File

@ -121,7 +121,7 @@ do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, int flags)
} }
int int
do_unmount(const char *mntpt, int flags) do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags)
{ {
if (unmount(mntpt, flags) < 0) if (unmount(mntpt, flags) < 0)
return (errno); return (errno);

View File

@ -374,7 +374,7 @@ do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, int flags)
} }
int int
do_unmount(const char *mntpt, int flags) do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags)
{ {
if (!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { if (!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
int rv = umount2(mntpt, flags); int rv = umount2(mntpt, flags);