]> git.proxmox.com Git - mirror_zfs.git/commitdiff
zfs get: don't lookup mount options when using "-s local"
authorAlan Somers <asomers@gmail.com>
Thu, 29 Apr 2021 21:19:44 +0000 (15:19 -0600)
committerGitHub <noreply@github.com>
Thu, 29 Apr 2021 21:19:44 +0000 (14:19 -0700)
Looking up mount options can be very expensive on servers with many
mounted file systems.  When doing "zfs get" with any "-s" option that
does not include "temporary", the mount list will never be used.  This
commit optimizes for that case.

This is a breaking commit for libzfs!  Callers of zfs_get_prop are now
required to initialize src.  To preserve existing behavior, they should
initialize it to ZPROP_SRC_NONE.

Sponsored by: Axcient
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alan Somers <asomers@gmail.com>
Closes #11955

cmd/zfs/zfs_main.c
lib/libzfs/libzfs_dataset.c
lib/libzfs/libzfs_diff.c
lib/libzfs/libzfs_mount.c
lib/libzfs/libzfs_sendrecv.c

index 24ff074c4ee03243606e1c285fe6487c3de7173d..9859a866f754d868abe10abe68223b737d063a63 100644 (file)
@@ -1882,7 +1882,6 @@ get_callback(zfs_handle_t *zhp, void *data)
 {
        char buf[ZFS_MAXPROPLEN];
        char rbuf[ZFS_MAXPROPLEN];
-       zprop_source_t sourcetype;
        char source[ZFS_MAX_DATASET_NAME_LEN];
        zprop_get_cbdata_t *cbp = data;
        nvlist_t *user_props = zfs_get_user_props(zhp);
@@ -1893,6 +1892,7 @@ get_callback(zfs_handle_t *zhp, void *data)
        boolean_t received = is_recvd_column(cbp);
 
        for (; pl != NULL; pl = pl->pl_next) {
+               zprop_source_t sourcetype = cbp->cb_sources;
                char *recvdval = NULL;
                /*
                 * Skip the special fake placeholder.  This will also skip over
@@ -4660,7 +4660,7 @@ zfs_do_send(int argc, char **argv)
         */
        if (fromname && (cp = strchr(fromname, '@')) != NULL) {
                char origin[ZFS_MAX_DATASET_NAME_LEN];
-               zprop_source_t src;
+               zprop_source_t src = ZPROP_SRC_NONE;
 
                (void) zfs_prop_get(zhp, ZFS_PROP_ORIGIN,
                    origin, sizeof (origin), &src, NULL, 0, B_FALSE);
index 823fcb284d2e5d68f48580d8b07b542d286c2b3b..dd2572b0166c6c982be3a2af793197c544157bb6 100644 (file)
@@ -2180,7 +2180,8 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
         * its presence.
         */
        if (!zhp->zfs_mntcheck &&
-           (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
+           (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED) &&
+           (src && (*src & ZPROP_SRC_TEMPORARY))) {
                libzfs_handle_t *hdl = zhp->zfs_hdl;
                struct mnttab entry;
 
@@ -2595,9 +2596,16 @@ zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval,
 }
 
 /*
- * Retrieve a property from the given object.  If 'literal' is specified, then
- * numbers are left as exact values.  Otherwise, numbers are converted to a
- * human-readable form.
+ * Retrieve a property from the given object.
+ *
+ * Arguments:
+ *  src :      On call, this must contain the bitmap of ZPROP_SRC_* types to
+ *             query.  Properties whose values come from a different source
+ *             may not be returned. NULL will be treated as ZPROP_SRC_ALL.  On
+ *             return, if not NULL, this variable will contain the source for
+ *             the queried property.
+ *  literal :  If specified, then numbers are left as exact values.  Otherwise,
+ *             they are converted to a human-readable form.
  *
  * Returns 0 on success, or -1 on error.
  */
@@ -2620,9 +2628,6 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
        if (received && zfs_prop_readonly(prop))
                return (-1);
 
-       if (src)
-               *src = ZPROP_SRC_NONE;
-
        switch (prop) {
        case ZFS_PROP_CREATION:
                /*
index 12e079b0eeb714e2c1d57f25a27d4cd68f9313b3..1eda8bad1feca0addd14528eb16e302babea786a 100644 (file)
@@ -575,7 +575,7 @@ get_snapshot_names(differ_info_t *di, const char *fromsnap,
                 * tosnap is a clone of a fromsnap descendant.
                 */
                char origin[ZFS_MAX_DATASET_NAME_LEN];
-               zprop_source_t src;
+               zprop_source_t src = ZPROP_SRC_NONE;
                zfs_handle_t *zhp;
 
                di->ds = zfs_alloc(di->zhp->zfs_hdl, tdslen + 1);
index 3df42e2dc3e11255cddf18471762f41f072b89eb..37958a34269027b4abae176ea7dc27ea39d966e2 100644 (file)
@@ -266,7 +266,7 @@ zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
     zprop_source_t *source, int flags)
 {
        char sourceloc[MAXNAMELEN];
-       zprop_source_t sourcetype;
+       zprop_source_t sourcetype = ZPROP_SRC_NONE;
 
        if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type,
            B_FALSE))
@@ -765,7 +765,7 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
        char shareopts[ZFS_MAXPROPLEN];
        char sourcestr[ZFS_MAXPROPLEN];
        zfs_share_proto_t *curr_proto;
-       zprop_source_t sourcetype;
+       zprop_source_t sourcetype = ZPROP_SRC_NONE;
        int err = 0;
 
        if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL, 0))
index 511895d1865884e1ae406118f27cbecc6fbeefa8..8c55d604497b1bd8185f3eaf69b67f9798541586 100644 (file)
@@ -2662,7 +2662,7 @@ static zfs_handle_t *
 recv_open_grand_origin(zfs_handle_t *zhp)
 {
        char origin[ZFS_MAX_DATASET_NAME_LEN];
-       zprop_source_t src;
+       zprop_source_t src = ZPROP_SRC_NONE;
        zfs_handle_t *ozhp = zfs_handle_dup(zhp);
 
        while (ozhp != NULL) {