Add linux mlslabel support
[zfs.git] / module / zfs / zfs_ioctl.c
index 1b63c9b..2302c0f 100644 (file)
@@ -166,7 +166,7 @@ history_str_get(zfs_cmd_t *zc)
 {
        char *buf;
 
-       if (zc->zc_history == NULL)
+       if (zc->zc_history == 0)
                return (NULL);
 
        buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
@@ -384,6 +384,7 @@ zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
 static int
 zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
 {
+#ifdef HAVE_MLSLABEL
        char            ds_hexsl[MAXNAMELEN];
        bslabel_t       ds_sl, new_sl;
        boolean_t       new_default = FALSE;
@@ -471,6 +472,9 @@ out_check:
        if (needed_priv != -1)
                return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
        return (0);
+#else
+       return ENOTSUP;
+#endif /* HAVE_MLSLABEL */
 }
 
 static int
@@ -483,6 +487,8 @@ zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
         * Check permissions for special properties.
         */
        switch (prop) {
+       default:
+               break;
        case ZFS_PROP_ZONED:
                /*
                 * Disallow setting of 'zoned' from within a local zone.
@@ -1162,8 +1168,8 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
        nvlist_t *zplprops = NULL;
        char *buf;
 
-       if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
-           zc->zc_iflags, &config))
+       if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+           zc->zc_iflags, &config)))
                return (error);
 
        if (zc->zc_nvlist_src_size != 0 && (error =
@@ -1452,7 +1458,7 @@ zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
 {
        int error;
 
-       if (error = dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value))
+       if ((error = dsl_dsobj_to_dsname(zc->zc_name,zc->zc_obj,zc->zc_value)))
                return (error);
 
        return (0);
@@ -1668,8 +1674,8 @@ zfs_ioc_vdev_split(zfs_cmd_t *zc)
        if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
                return (error);
 
-       if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
-           zc->zc_iflags, &config)) {
+       if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+           zc->zc_iflags, &config))) {
                spa_close(spa, FTAG);
                return (error);
        }
@@ -1746,9 +1752,10 @@ zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
                 */
                if (!zc->zc_objset_stats.dds_inconsistent) {
                        if (dmu_objset_type(os) == DMU_OST_ZVOL)
-                               VERIFY(zvol_get_stats(os, nv) == 0);
+                               error = zvol_get_stats(os, nv);
                }
-               error = put_nvlist(zc, nv);
+               if (error == 0)
+                       error = put_nvlist(zc, nv);
                nvlist_free(nv);
        }
 
@@ -1771,7 +1778,7 @@ zfs_ioc_objset_stats(zfs_cmd_t *zc)
        objset_t *os = NULL;
        int error;
 
-       if (error = dmu_objset_hold(zc->zc_name, FTAG, &os))
+       if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)))
                return (error);
 
        error = zfs_ioc_objset_stats_impl(zc, os);
@@ -1801,7 +1808,7 @@ zfs_ioc_objset_recvd_props(zfs_cmd_t *zc)
        int error;
        nvlist_t *nv;
 
-       if (error = dmu_objset_hold(zc->zc_name, FTAG, &os))
+       if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)))
                return (error);
 
        /*
@@ -1856,7 +1863,7 @@ zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
        int err;
 
        /* XXX reading without owning */
-       if (err = dmu_objset_hold(zc->zc_name, FTAG, &os))
+       if ((err = dmu_objset_hold(zc->zc_name, FTAG, &os)))
                return (err);
 
        dmu_objset_fast_stat(os, &zc->zc_objset_stats);
@@ -1866,7 +1873,7 @@ zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
         * which we aren't supposed to do with a DS_MODE_USER
         * hold, because it could be inconsistent.
         */
-       if (zc->zc_nvlist_dst != NULL &&
+       if (zc->zc_nvlist_dst != 0 &&
            !zc->zc_objset_stats.dds_inconsistent &&
            dmu_objset_type(os) == DMU_OST_ZFS) {
                nvlist_t *nv;
@@ -1924,7 +1931,7 @@ zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
        size_t orig_len = strlen(zc->zc_name);
 
 top:
-       if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) {
+       if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os))) {
                if (error == ENOENT)
                        error = ESRCH;
                return (error);
@@ -2366,8 +2373,8 @@ zfs_check_userprops(char *fsname, nvlist_t *nvl)
                    nvpair_type(pair) != DATA_TYPE_STRING)
                        return (EINVAL);
 
-               if (error = zfs_secpolicy_write_perms(fsname,
-                   ZFS_DELEG_PERM_USERPROP, CRED()))
+               if ((error = zfs_secpolicy_write_perms(fsname,
+                   ZFS_DELEG_PERM_USERPROP, CRED())))
                        return (error);
 
                if (strlen(propname) >= ZAP_MAXNAMELEN)
@@ -2458,7 +2465,7 @@ zfs_ioc_set_prop(zfs_cmd_t *zc)
 
        error = zfs_set_prop_nvlist(zc->zc_name, source, nvl, &errors);
 
-       if (zc->zc_nvlist_dst != NULL && errors != NULL) {
+       if (zc->zc_nvlist_dst != 0 && errors != NULL) {
                (void) put_nvlist(zc, errors);
        }
 
@@ -2550,8 +2557,8 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc)
        int error;
        nvpair_t *pair;
 
-       if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
-           zc->zc_iflags, &props))
+       if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+           zc->zc_iflags, &props)))
                return (error);
 
        /*
@@ -2609,7 +2616,7 @@ zfs_ioc_pool_get_props(zfs_cmd_t *zc)
                spa_close(spa, FTAG);
        }
 
-       if (error == 0 && zc->zc_nvlist_dst != NULL)
+       if (error == 0 && zc->zc_nvlist_dst != 0)
                error = put_nvlist(zc, nvp);
        else
                error = EFAULT;
@@ -2917,7 +2924,7 @@ zfs_ioc_create(zfs_cmd_t *zc)
            strchr(zc->zc_name, '%'))
                return (EINVAL);
 
-       if (zc->zc_nvlist_src != NULL &&
+       if (zc->zc_nvlist_src != 0 &&
            (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
            zc->zc_iflags, &nvprops)) != 0)
                return (error);
@@ -3041,7 +3048,7 @@ zfs_ioc_snapshot(zfs_cmd_t *zc)
        if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
                return (EINVAL);
 
-       if (zc->zc_nvlist_src != NULL &&
+       if (zc->zc_nvlist_src != 0 &&
            (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
            zc->zc_iflags, &nvprops)) != 0)
                return (error);
@@ -3272,8 +3279,8 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
 
        if (prop == ZPROP_INVAL) {
                if (zfs_prop_user(propname)) {
-                       if (err = zfs_secpolicy_write_perms(dsname,
-                           ZFS_DELEG_PERM_USERPROP, cr))
+                       if ((err = zfs_secpolicy_write_perms(dsname,
+                           ZFS_DELEG_PERM_USERPROP, cr)))
                                return (err);
                        return (0);
                }
@@ -3296,7 +3303,7 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
                                return (EINVAL);
                        }
 
-                       if (err = zfs_secpolicy_write_perms(dsname, perm, cr))
+                       if ((err = zfs_secpolicy_write_perms(dsname, perm, cr)))
                                return (err);
                        return (0);
                }
@@ -3380,6 +3387,8 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
                                return (ENOTSUP);
                }
                break;
+       default:
+               break;
        }
 
        return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
@@ -3563,7 +3572,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
        tosnap = strchr(tofs, '@');
        *tosnap++ = '\0';
 
-       if (zc->zc_nvlist_src != NULL &&
+       if (zc->zc_nvlist_src != 0 &&
            (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
            zc->zc_iflags, &props)) != 0)
                return (error);
@@ -3919,7 +3928,7 @@ zfs_ioc_clear(zfs_cmd_t *zc)
                nvlist_t *policy;
                nvlist_t *config = NULL;
 
-               if (zc->zc_nvlist_src == NULL)
+               if (zc->zc_nvlist_src == 0)
                        return (EINVAL);
 
                if ((error = get_nvlist(zc->zc_nvlist_src,
@@ -4622,6 +4631,67 @@ zfs_ioc_get_holds(zfs_cmd_t *zc)
 }
 
 /*
+ * inputs:
+ * zc_guid             flags (ZEVENT_NONBLOCK)
+ *
+ * outputs:
+ * zc_nvlist_dst       next nvlist event
+ * zc_cookie           dropped events since last get
+ * zc_cleanup_fd       cleanup-on-exit file descriptor
+ */
+static int
+zfs_ioc_events_next(zfs_cmd_t *zc)
+{
+       zfs_zevent_t *ze;
+       nvlist_t *event = NULL;
+       minor_t minor;
+       uint64_t dropped = 0;
+       int error;
+
+       error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
+       if (error != 0)
+               return (error);
+
+       do {
+               error = zfs_zevent_next(ze, &event, &dropped);
+               if (event != NULL) {
+                       zc->zc_cookie = dropped;
+                       error = put_nvlist(zc, event);
+                       nvlist_free(event);
+               }
+
+               if (zc->zc_guid & ZEVENT_NONBLOCK)
+                       break;
+
+               if ((error == 0) || (error != ENOENT))
+                       break;
+
+               error = zfs_zevent_wait(ze);
+               if (error)
+                       break;
+       } while (1);
+
+       zfs_zevent_fd_rele(zc->zc_cleanup_fd);
+
+       return (error);
+}
+
+/*
+ * outputs:
+ * zc_cookie           cleared events count
+ */
+static int
+zfs_ioc_events_clear(zfs_cmd_t *zc)
+{
+       int count;
+
+       zfs_zevent_drain_all(&count);
+       zc->zc_cookie = count;
+
+       return 0;
+}
+
+/*
  * pool create, destroy, and export don't log the history as part of
  * zfsdev_ioctl, but rather zfs_ioc_pool_create, and zfs_ioc_pool_export
  * do the logging of those commands.
@@ -4742,7 +4812,11 @@ static zfs_ioc_vec_t zfs_ioc_vec[] = {
        { zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot, DATASET_NAME,
            B_FALSE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
        { zfs_ioc_obj_to_stats, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
-           POOL_CHECK_SUSPENDED }
+           POOL_CHECK_SUSPENDED },
+       { zfs_ioc_events_next, zfs_secpolicy_config, NO_NAME, B_FALSE,
+           POOL_CHECK_NONE },
+       { zfs_ioc_events_clear, zfs_secpolicy_config, NO_NAME, B_FALSE,
+           POOL_CHECK_NONE },
 };
 
 int