From 68398a5451b1a946e9f72ba8932930051bc4e9e5 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Sun, 25 Jan 2015 04:09:47 +0100 Subject: [PATCH 01/16] ssh: Raise WARNS back to 2. --- secure/usr.bin/ssh/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/secure/usr.bin/ssh/Makefile b/secure/usr.bin/ssh/Makefile index 5b872f414b..90d74a4bb2 100644 --- a/secure/usr.bin/ssh/Makefile +++ b/secure/usr.bin/ssh/Makefile @@ -4,7 +4,7 @@ PROG= ssh LINKS= ${BINDIR}/ssh ${BINDIR}/slogin MAN= ssh.1 ssh_config.5 MLINKS= ssh.1 slogin.1 -WARNS?= 0 +WARNS?= 2 SRCS= ssh.c readconf.c clientloop.c sshtty.c \ sshconnect.c sshconnect1.c sshconnect2.c mux.c \ -- 2.41.0 From 158486a6a57db6e82c3f8da282e6d6e37932d133 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Tigeot?= Date: Sun, 24 May 2015 08:53:21 +0100 Subject: [PATCH 02/16] drm: Implement and use the Linux version of kfree() --- sys/dev/drm/drm_bufs.c | 2 +- sys/dev/drm/drm_crtc_helper.c | 6 ++--- sys/dev/drm/drm_edid.c | 2 +- sys/dev/drm/drm_fb_helper.c | 2 +- sys/dev/drm/drm_hashtab.c | 2 +- sys/dev/drm/drm_linux_list_sort.c | 2 +- sys/dev/drm/drm_vm.c | 4 +-- sys/dev/drm/i915/i915_dma.c | 8 +++--- sys/dev/drm/i915/i915_gem.c | 6 ++--- sys/dev/drm/i915/i915_gem_context.c | 4 +-- sys/dev/drm/i915/i915_gem_gtt.c | 2 +- sys/dev/drm/i915/intel_crt.c | 4 +-- sys/dev/drm/i915/intel_ddi.c | 6 ++--- sys/dev/drm/i915/intel_display.c | 6 ++--- sys/dev/drm/i915/intel_dp.c | 14 +++++------ sys/dev/drm/i915/intel_fb.c | 4 +-- sys/dev/drm/i915/intel_hdmi.c | 2 +- sys/dev/drm/i915/intel_lvds.c | 12 ++++----- sys/dev/drm/i915/intel_modes.c | 2 +- sys/dev/drm/i915/intel_overlay.c | 10 ++++---- sys/dev/drm/i915/intel_pm.c | 4 +-- sys/dev/drm/i915/intel_ringbuffer.c | 4 +-- sys/dev/drm/i915/intel_sdvo.c | 6 ++--- sys/dev/drm/i915/intel_sprite.c | 6 ++--- sys/dev/drm/i915/intel_tv.c | 4 +-- sys/dev/drm/include/drm/drmP.h | 15 ++--------- sys/dev/drm/include/drm/drm_mem_util.h | 2 +- sys/dev/drm/include/linux/slab.h | 35 ++++++++++++++++++++++++++ sys/dev/drm/include/linux/workqueue.h | 2 +- sys/dev/drm/radeon/radeon_connectors.c | 2 +- sys/dev/drm/radeon/radeon_display.c | 2 +- sys/dev/drm/ttm/ttm_bo.c | 8 +++--- sys/dev/drm/ttm/ttm_bo_manager.c | 4 +-- sys/dev/drm/ttm/ttm_bo_util.c | 2 +- 34 files changed, 110 insertions(+), 86 deletions(-) create mode 100644 sys/dev/drm/include/linux/slab.h diff --git a/sys/dev/drm/drm_bufs.c b/sys/dev/drm/drm_bufs.c index ef4576695d..09e1faba35 100644 --- a/sys/dev/drm/drm_bufs.c +++ b/sys/dev/drm/drm_bufs.c @@ -233,7 +233,7 @@ int drm_addmap(struct drm_device * dev, resource_size_t offset, * need to point to a 64bit variable first. */ dmah = drm_pci_alloc(dev, map->size, map->size); if (!dmah) { - kfree(map, M_DRM); + kfree(map); return -ENOMEM; } map->handle = dmah->vaddr; diff --git a/sys/dev/drm/drm_crtc_helper.c b/sys/dev/drm/drm_crtc_helper.c index 6dd27080d4..03367cac5d 100644 --- a/sys/dev/drm/drm_crtc_helper.c +++ b/sys/dev/drm/drm_crtc_helper.c @@ -787,9 +787,9 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) } } - kfree(save_connectors, M_DRM); - kfree(save_encoders, M_DRM); - kfree(save_crtcs, M_DRM); + kfree(save_connectors); + kfree(save_encoders); + kfree(save_crtcs); return 0; fail: diff --git a/sys/dev/drm/drm_edid.c b/sys/dev/drm/drm_edid.c index 1c0fd56f31..b66e4c122a 100644 --- a/sys/dev/drm/drm_edid.c +++ b/sys/dev/drm/drm_edid.c @@ -1135,7 +1135,7 @@ carp: connector->bad_edid_counter++; out: - kfree(block, M_DRM); + kfree(block); return NULL; } diff --git a/sys/dev/drm/drm_fb_helper.c b/sys/dev/drm/drm_fb_helper.c index cf9879250b..bb8d2d4847 100644 --- a/sys/dev/drm/drm_fb_helper.c +++ b/sys/dev/drm/drm_fb_helper.c @@ -466,7 +466,7 @@ int drm_fb_helper_init(struct drm_device *dev, sizeof(struct drm_fb_helper_connector *), M_DRM, M_WAITOK | M_ZERO); if (!fb_helper->connector_info) { - kfree(fb_helper->crtc_info, M_DRM); + kfree(fb_helper->crtc_info); return -ENOMEM; } fb_helper->connector_count = 0; diff --git a/sys/dev/drm/drm_hashtab.c b/sys/dev/drm/drm_hashtab.c index 55b996e782..bbea5f7008 100644 --- a/sys/dev/drm/drm_hashtab.c +++ b/sys/dev/drm/drm_hashtab.c @@ -198,7 +198,7 @@ EXPORT_SYMBOL(drm_ht_remove_item); void drm_ht_remove(struct drm_open_hash *ht) { if (ht->table) { - kfree(ht->table, M_DRM); + kfree(ht->table); ht->table = NULL; } } diff --git a/sys/dev/drm/drm_linux_list_sort.c b/sys/dev/drm/drm_linux_list_sort.c index 1d24b775f4..1d07cf0a6c 100644 --- a/sys/dev/drm/drm_linux_list_sort.c +++ b/sys/dev/drm/drm_linux_list_sort.c @@ -72,5 +72,5 @@ drm_list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, INIT_LIST_HEAD(head); for (i = 0; i < count; i++) list_add_tail(ar[i], head); - kfree(ar, M_TEMP); + kfree(ar); } diff --git a/sys/dev/drm/drm_vm.c b/sys/dev/drm/drm_vm.c index 6244370aca..2f01e648a7 100644 --- a/sys/dev/drm/drm_vm.c +++ b/sys/dev/drm/drm_vm.c @@ -201,7 +201,7 @@ vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end, } } mtx_unlock(&vm_phys_fictitious_reg_mtx); - kfree(fp, M_DRM); + kfree(fp); return (EBUSY); } @@ -220,7 +220,7 @@ vm_phys_fictitious_unreg_range(vm_paddr_t start, vm_paddr_t end) fp = seg->first_page; seg->first_page = NULL; mtx_unlock(&vm_phys_fictitious_reg_mtx); - kfree(fp, M_DRM); + kfree(fp); return; } } diff --git a/sys/dev/drm/i915/i915_dma.c b/sys/dev/drm/i915/i915_dma.c index c696eeae10..54c771cca9 100644 --- a/sys/dev/drm/i915/i915_dma.c +++ b/sys/dev/drm/i915/i915_dma.c @@ -657,7 +657,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); fail_free: - kfree(cliprects, M_DRM); + kfree(cliprects); return ret; } @@ -1573,7 +1573,7 @@ out_gem_unload: out_mtrrfree: put_bridge: free_priv: - kfree(dev_priv, M_DRM); + kfree(dev_priv); return ret; } @@ -1625,7 +1625,7 @@ int i915_driver_unload(struct drm_device *dev) * config parsed from VBT */ if (dev_priv->child_dev && dev_priv->child_dev_num) { - kfree(dev_priv->child_dev, M_DRM); + kfree(dev_priv->child_dev); dev_priv->child_dev = NULL; dev_priv->child_dev_num = 0; } @@ -1736,7 +1736,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; - kfree(file_priv, M_DRM); + kfree(file_priv); } struct drm_ioctl_desc i915_ioctls[] = { diff --git a/sys/dev/drm/i915/i915_gem.c b/sys/dev/drm/i915/i915_gem.c index e02738d81c..edf5db9acf 100644 --- a/sys/dev/drm/i915/i915_gem.c +++ b/sys/dev/drm/i915/i915_gem.c @@ -1646,7 +1646,7 @@ i915_add_request(struct intel_ring_buffer *ring, ret = ring->add_request(ring); if (ret) { - kfree(request, M_DRM); + kfree(request); return ret; } @@ -1809,7 +1809,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) list_del(&request->list); i915_gem_request_remove_from_client(request); - kfree(request, M_DRM); + kfree(request); } /* Move any buffers on the active list that are no longer referenced @@ -3405,7 +3405,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, return NULL; if (drm_gem_object_init(dev, &obj->base, size) != 0) { - kfree(obj, M_DRM); + kfree(obj); return NULL; } diff --git a/sys/dev/drm/i915/i915_gem_context.c b/sys/dev/drm/i915/i915_gem_context.c index 237af0446a..fed7afd001 100644 --- a/sys/dev/drm/i915/i915_gem_context.c +++ b/sys/dev/drm/i915/i915_gem_context.c @@ -131,7 +131,7 @@ static void do_destroy(struct i915_hw_context *ctx) idr_remove(&ctx->file_priv->context_idr, ctx->id); drm_gem_object_unreference(&ctx->obj->base); - kfree(ctx, M_DRM); + kfree(ctx); } static struct i915_hw_context * @@ -148,7 +148,7 @@ create_hw_context(struct drm_device *dev, ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); if (ctx->obj == NULL) { - kfree(ctx, M_DRM); + kfree(ctx); DRM_DEBUG_DRIVER("Context object allocated failed\n"); return ERR_PTR(-ENOMEM); } diff --git a/sys/dev/drm/i915/i915_gem_gtt.c b/sys/dev/drm/i915/i915_gem_gtt.c index 21105f950d..88df8f8a5f 100644 --- a/sys/dev/drm/i915/i915_gem_gtt.c +++ b/sys/dev/drm/i915/i915_gem_gtt.c @@ -234,7 +234,7 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) ret = gen6_ppgtt_init(ppgtt); if (ret) - kfree(ppgtt, M_DRM); + kfree(ppgtt); else dev_priv->mm.aliasing_ppgtt = ppgtt; diff --git a/sys/dev/drm/i915/intel_crt.c b/sys/dev/drm/i915/intel_crt.c index 8886d4da29..601e0b6436 100644 --- a/sys/dev/drm/i915/intel_crt.c +++ b/sys/dev/drm/i915/intel_crt.c @@ -410,7 +410,7 @@ static int intel_crt_ddc_get_modes(struct drm_connector *connector, return 0; ret = intel_connector_update_modes(connector, edid); - kfree(edid, M_DRM); + kfree(edid); return ret; } @@ -735,7 +735,7 @@ void intel_crt_init(struct drm_device *dev) intel_connector = kmalloc(sizeof(struct intel_connector), M_DRM, M_WAITOK | M_ZERO); if (!intel_connector) { - kfree(crt, M_DRM); + kfree(crt); return; } diff --git a/sys/dev/drm/i915/intel_ddi.c b/sys/dev/drm/i915/intel_ddi.c index f3ea7a20c0..83a3fda0ed 100644 --- a/sys/dev/drm/i915/intel_ddi.c +++ b/sys/dev/drm/i915/intel_ddi.c @@ -1510,7 +1510,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) dp_connector = kmalloc(sizeof(struct intel_connector), M_DRM, M_WAITOK | M_ZERO); if (!dp_connector) { - kfree(intel_dig_port, M_DRM); + kfree(intel_dig_port); return; } @@ -1518,8 +1518,8 @@ void intel_ddi_init(struct drm_device *dev, enum port port) hdmi_connector = kmalloc(sizeof(struct intel_connector), M_DRM, M_WAITOK | M_ZERO); if (!hdmi_connector) { - kfree(dp_connector, M_DRM); - kfree(intel_dig_port, M_DRM); + kfree(dp_connector); + kfree(intel_dig_port); return; } } diff --git a/sys/dev/drm/i915/intel_display.c b/sys/dev/drm/i915/intel_display.c index 63a3be9a13..729290acb7 100644 --- a/sys/dev/drm/i915/intel_display.c +++ b/sys/dev/drm/i915/intel_display.c @@ -6514,7 +6514,7 @@ intel_framebuffer_create(struct drm_device *dev, ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); if (ret) { drm_gem_object_unreference_unlocked(&obj->base); - kfree(intel_fb, M_DRM); + kfree(intel_fb); return ERR_PTR(ret); } @@ -6959,7 +6959,7 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) if (work) { cancel_work_sync(&work->work); - kfree(work, M_DRM); + kfree(work); } drm_crtc_cleanup(crtc); @@ -7906,7 +7906,7 @@ done: } out: - kfree(saved_mode, M_DRM); + kfree(saved_mode); return ret; } diff --git a/sys/dev/drm/i915/intel_dp.c b/sys/dev/drm/i915/intel_dp.c index caa4e95145..766c0894d6 100644 --- a/sys/dev/drm/i915/intel_dp.c +++ b/sys/dev/drm/i915/intel_dp.c @@ -2395,7 +2395,7 @@ intel_dp_detect(struct drm_connector *connector, bool force) edid = intel_dp_get_edid(connector, intel_dp->adapter); if (edid) { intel_dp->has_audio = drm_detect_monitor_audio(edid); - kfree(edid, M_DRM); + kfree(edid); } } @@ -2441,7 +2441,7 @@ intel_dp_detect_audio(struct drm_connector *connector) edid = intel_dp_get_edid(connector, intel_dp->adapter); if (edid) { has_audio = drm_detect_monitor_audio(edid); - kfree(edid, M_DRM); + kfree(edid); } return has_audio; @@ -2534,7 +2534,7 @@ intel_dp_destroy(struct drm_connector *connector) struct intel_connector *intel_connector = to_intel_connector(connector); if (!IS_ERR_OR_NULL(intel_connector->edid)) - kfree(intel_connector->edid, M_DRM); + kfree(intel_connector->edid); if (is_edp(intel_dp)) intel_panel_fini(&intel_connector->panel); @@ -2543,7 +2543,7 @@ intel_dp_destroy(struct drm_connector *connector) drm_sysfs_connector_remove(connector); #endif drm_connector_cleanup(connector); - kfree(connector, M_DRM); + kfree(connector); } void intel_dp_encoder_destroy(struct drm_encoder *encoder) @@ -2566,7 +2566,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) ironlake_panel_vdd_off_sync(intel_dp); mutex_unlock(&dev->mode_config.mutex); } - kfree(intel_dig_port, M_DRM); + kfree(intel_dig_port); } static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { @@ -2906,7 +2906,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, drm_mode_connector_update_edid_property(connector, edid); drm_edid_to_eld(connector, edid); } else { - kfree(edid, M_DRM); + kfree(edid); edid = ERR_PTR(-EINVAL); } } else { @@ -2965,7 +2965,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_connector = kmalloc(sizeof(struct intel_connector), M_DRM, M_WAITOK | M_ZERO); if (!intel_connector) { - kfree(intel_dig_port, M_DRM); + kfree(intel_dig_port); return; } diff --git a/sys/dev/drm/i915/intel_fb.c b/sys/dev/drm/i915/intel_fb.c index 9391ab5bf4..e313151777 100644 --- a/sys/dev/drm/i915/intel_fb.c +++ b/sys/dev/drm/i915/intel_fb.c @@ -237,7 +237,7 @@ int intel_fbdev_init(struct drm_device *dev) dev_priv->num_pipe, INTELFB_CONN_LIMIT); if (ret) { - kfree(ifbdev, M_DRM); + kfree(ifbdev); return ret; } @@ -262,7 +262,7 @@ void intel_fbdev_fini(struct drm_device *dev) return; intel_fbdev_destroy(dev, dev_priv->fbdev); - kfree(dev_priv->fbdev, M_DRM); + kfree(dev_priv->fbdev); dev_priv->fbdev = NULL; } diff --git a/sys/dev/drm/i915/intel_hdmi.c b/sys/dev/drm/i915/intel_hdmi.c index 4ee3c8e807..9a2b581a41 100644 --- a/sys/dev/drm/i915/intel_hdmi.c +++ b/sys/dev/drm/i915/intel_hdmi.c @@ -1067,7 +1067,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port) intel_connector = kmalloc(sizeof(struct intel_connector), M_DRM, M_WAITOK | M_ZERO); if (!intel_connector) { - kfree(intel_dig_port, M_DRM); + kfree(intel_dig_port); return; } diff --git a/sys/dev/drm/i915/intel_lvds.c b/sys/dev/drm/i915/intel_lvds.c index f49644bf58..62eee29fdc 100644 --- a/sys/dev/drm/i915/intel_lvds.c +++ b/sys/dev/drm/i915/intel_lvds.c @@ -618,7 +618,7 @@ static void intel_lvds_destroy(struct drm_connector *connector) #endif if (!IS_ERR_OR_NULL(lvds_connector->base.edid)) - kfree(lvds_connector->base.edid, M_DRM); + kfree(lvds_connector->base.edid); intel_panel_fini(&lvds_connector->base.panel); @@ -626,7 +626,7 @@ static void intel_lvds_destroy(struct drm_connector *connector) drm_sysfs_connector_remove(connector); #endif drm_connector_cleanup(connector); - kfree(connector, M_DRM); + kfree(connector); } static int intel_lvds_set_property(struct drm_connector *connector, @@ -1092,7 +1092,7 @@ bool intel_lvds_init(struct drm_device *dev) lvds_connector = kmalloc(sizeof(struct intel_lvds_connector), M_DRM, M_WAITOK | M_ZERO); if (!lvds_connector) { - kfree(lvds_encoder, M_DRM); + kfree(lvds_encoder); return false; } @@ -1168,7 +1168,7 @@ bool intel_lvds_init(struct drm_device *dev) drm_mode_connector_update_edid_property(connector, edid); } else { - kfree(edid, M_DRM); + kfree(edid); edid = ERR_PTR(-EINVAL); } } else { @@ -1277,7 +1277,7 @@ failed: drm_encoder_cleanup(encoder); if (fixed_mode) drm_mode_destroy(dev, fixed_mode); - kfree(lvds_encoder, M_DRM); - kfree(lvds_connector, M_DRM); + kfree(lvds_encoder); + kfree(lvds_connector); return false; } diff --git a/sys/dev/drm/i915/intel_modes.c b/sys/dev/drm/i915/intel_modes.c index 94af089176..5d2702cbde 100644 --- a/sys/dev/drm/i915/intel_modes.c +++ b/sys/dev/drm/i915/intel_modes.c @@ -64,7 +64,7 @@ int intel_ddc_get_modes(struct drm_connector *connector, return 0; ret = intel_connector_update_modes(connector, edid); - kfree(edid, M_DRM); + kfree(edid); return ret; } diff --git a/sys/dev/drm/i915/intel_overlay.c b/sys/dev/drm/i915/intel_overlay.c index c7bb232488..cc1f3cb20c 100644 --- a/sys/dev/drm/i915/intel_overlay.c +++ b/sys/dev/drm/i915/intel_overlay.c @@ -1160,7 +1160,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, mutex_unlock(&dev->struct_mutex); drm_modeset_unlock_all(dev); - kfree(params, M_DRM); + kfree(params); return 0; @@ -1169,7 +1169,7 @@ out_unlock: drm_modeset_unlock_all(dev); drm_gem_object_unreference_unlocked(&new_bo->base); out_free: - kfree(params, M_DRM); + kfree(params); return ret; } @@ -1392,7 +1392,7 @@ out_free_bo: drm_gem_object_unreference(®_bo->base); out_free: mutex_unlock(&dev->struct_mutex); - kfree(overlay, M_DRM); + kfree(overlay); return; } @@ -1409,7 +1409,7 @@ void intel_cleanup_overlay(struct drm_device *dev) BUG_ON(dev_priv->overlay->active); drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base); - kfree(dev_priv->overlay, M_DRM); + kfree(dev_priv->overlay); } #ifdef CONFIG_DEBUG_FS @@ -1480,7 +1480,7 @@ intel_overlay_capture_error_state(struct drm_device *dev) return error; err: - kfree(error, M_DRM); + kfree(error); return NULL; } diff --git a/sys/dev/drm/i915/intel_pm.c b/sys/dev/drm/i915/intel_pm.c index b2bc61f77b..f63e51b980 100644 --- a/sys/dev/drm/i915/intel_pm.c +++ b/sys/dev/drm/i915/intel_pm.c @@ -288,7 +288,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) } mutex_unlock(&dev->struct_mutex); - kfree(work, M_DRM); + kfree(work); } static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) @@ -304,7 +304,7 @@ static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) */ if (cancel_delayed_work(&dev_priv->fbc_work->work)) /* tasklet was killed before being run, clean up */ - kfree(dev_priv->fbc_work, M_DRM); + kfree(dev_priv->fbc_work); /* Mark the work as no longer wanted so that if it does * wake-up (because the work was already running and waiting diff --git a/sys/dev/drm/i915/intel_ringbuffer.c b/sys/dev/drm/i915/intel_ringbuffer.c index a2f1f4aee4..39fd071dac 100644 --- a/sys/dev/drm/i915/intel_ringbuffer.c +++ b/sys/dev/drm/i915/intel_ringbuffer.c @@ -483,7 +483,7 @@ err_unpin: err_unref: drm_gem_object_unreference(&obj->base); err: - kfree(pc, M_DRM); + kfree(pc); return ret; } @@ -503,7 +503,7 @@ cleanup_pipe_control(struct intel_ring_buffer *ring) i915_gem_object_unpin(obj); drm_gem_object_unreference(&obj->base); - kfree(pc, M_DRM); + kfree(pc); ring->private = NULL; } diff --git a/sys/dev/drm/i915/intel_sdvo.c b/sys/dev/drm/i915/intel_sdvo.c index e632385a7a..b2d297a30f 100644 --- a/sys/dev/drm/i915/intel_sdvo.c +++ b/sys/dev/drm/i915/intel_sdvo.c @@ -1595,7 +1595,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) else ret = connector_status_disconnected; - kfree(edid, M_DRM); + kfree(edid); } else ret = connector_status_connected; } @@ -2824,7 +2824,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, intel_sdvo) >> 1; intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg); if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev, sdvo_reg)) { - kfree(intel_sdvo, M_DRM); + kfree(intel_sdvo); return false; } @@ -2925,7 +2925,7 @@ err_output: err: drm_encoder_cleanup(&intel_encoder->base); intel_sdvo_unselect_i2c_bus(intel_sdvo); - kfree(intel_sdvo, M_DRM); + kfree(intel_sdvo); return false; } diff --git a/sys/dev/drm/i915/intel_sprite.c b/sys/dev/drm/i915/intel_sprite.c index 95baf510e8..6347181dd1 100644 --- a/sys/dev/drm/i915/intel_sprite.c +++ b/sys/dev/drm/i915/intel_sprite.c @@ -582,7 +582,7 @@ static void intel_destroy_plane(struct drm_plane *plane) struct intel_plane *intel_plane = to_intel_plane(plane); intel_disable_plane(plane); drm_plane_cleanup(plane); - kfree(intel_plane, M_DRM); + kfree(intel_plane); } int intel_sprite_set_colorkey(struct drm_device *dev, void *data, @@ -722,7 +722,7 @@ intel_plane_init(struct drm_device *dev, enum i915_pipe pipe) break; default: - kfree(intel_plane, M_DRM); + kfree(intel_plane); return -ENODEV; } @@ -733,7 +733,7 @@ intel_plane_init(struct drm_device *dev, enum i915_pipe pipe) plane_formats, num_plane_formats, false); if (ret) - kfree(intel_plane, M_DRM); + kfree(intel_plane); return ret; } diff --git a/sys/dev/drm/i915/intel_tv.c b/sys/dev/drm/i915/intel_tv.c index b7ee87a789..5e19217edb 100644 --- a/sys/dev/drm/i915/intel_tv.c +++ b/sys/dev/drm/i915/intel_tv.c @@ -1430,7 +1430,7 @@ intel_tv_destroy(struct drm_connector *connector) drm_sysfs_connector_remove(connector); #endif drm_connector_cleanup(connector); - kfree(connector, M_DRM); + kfree(connector); } @@ -1598,7 +1598,7 @@ intel_tv_init(struct drm_device *dev) intel_connector = kmalloc(sizeof(struct intel_connector), M_DRM, M_WAITOK | M_ZERO); if (!intel_connector) { - kfree(intel_tv, M_DRM); + kfree(intel_tv); return; } diff --git a/sys/dev/drm/include/drm/drmP.h b/sys/dev/drm/include/drm/drmP.h index d0578c39fb..4bb7b6f80c 100644 --- a/sys/dev/drm/include/drm/drmP.h +++ b/sys/dev/drm/include/drm/drmP.h @@ -107,6 +107,7 @@ MALLOC_DECLARE(M_DRM); #include #include #include +#include #include #include #include @@ -1541,22 +1542,10 @@ drm_calloc(size_t nmemb, size_t size, struct malloc_type *area) return kmalloc(size * nmemb, area, M_WAITOK | M_NULLOK | M_ZERO); } -static __inline__ void * -drm_realloc(void *oldpt, size_t oldsize, size_t size, - struct malloc_type *area) -{ - void *res; - res = krealloc(oldpt, size, area, M_WAITOK | M_NULLOK); - if (res == NULL && oldpt != NULL) - kfree(oldpt,area); - return res; -} - static __inline__ void drm_free(void *pt, struct malloc_type *area) { - if (pt != NULL) - kfree(pt, area); + kfree(pt); } /* Inline replacements for DRM_IOREMAP macros */ diff --git a/sys/dev/drm/include/drm/drm_mem_util.h b/sys/dev/drm/include/drm/drm_mem_util.h index 46bca01d3e..3adf183e8a 100644 --- a/sys/dev/drm/include/drm/drm_mem_util.h +++ b/sys/dev/drm/include/drm/drm_mem_util.h @@ -49,7 +49,7 @@ static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) static __inline void drm_free_large(void *ptr) { - kfree(ptr, M_DRM); + kfree(ptr); } #endif diff --git a/sys/dev/drm/include/linux/slab.h b/sys/dev/drm/include/linux/slab.h new file mode 100644 index 0000000000..4053d4d6e6 --- /dev/null +++ b/sys/dev/drm/include/linux/slab.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 François Tigeot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LINUX_SLAB_H_ +#define _LINUX_SLAB_H_ + +#define kfree(ptr) do { \ + if (ptr != NULL) \ + kfree(ptr, M_DRM); \ +} while (0) + +#endif /* _LINUX_SLAB_H_ */ diff --git a/sys/dev/drm/include/linux/workqueue.h b/sys/dev/drm/include/linux/workqueue.h index 90e59b5ee9..c5f82fcd85 100644 --- a/sys/dev/drm/include/linux/workqueue.h +++ b/sys/dev/drm/include/linux/workqueue.h @@ -163,7 +163,7 @@ static inline void destroy_workqueue(struct workqueue_struct *wq) { taskqueue_free(wq->taskqueue); - kfree(wq, M_DRM); + kfree(wq); } #define flush_workqueue(wq) flush_taskqueue((wq)->taskqueue) diff --git a/sys/dev/drm/radeon/radeon_connectors.c b/sys/dev/drm/radeon/radeon_connectors.c index 7fc287c6e1..4baddc43c4 100644 --- a/sys/dev/drm/radeon/radeon_connectors.c +++ b/sys/dev/drm/radeon/radeon_connectors.c @@ -1876,7 +1876,7 @@ radeon_add_atom_connector(struct drm_device *dev, failed: drm_connector_cleanup(connector); - kfree(connector, M_DRM); + kfree(connector); } void diff --git a/sys/dev/drm/radeon/radeon_display.c b/sys/dev/drm/radeon/radeon_display.c index a7104e3f80..5cec7e31a9 100644 --- a/sys/dev/drm/radeon/radeon_display.c +++ b/sys/dev/drm/radeon/radeon_display.c @@ -1124,7 +1124,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); if (ret) { - kfree(radeon_fb, M_DRM); + kfree(radeon_fb); drm_gem_object_unreference_unlocked(obj); return ERR_PTR(ret); } diff --git a/sys/dev/drm/ttm/ttm_bo.c b/sys/dev/drm/ttm/ttm_bo.c index 66adfc078b..6a0336e235 100644 --- a/sys/dev/drm/ttm/ttm_bo.c +++ b/sys/dev/drm/ttm/ttm_bo.c @@ -128,7 +128,7 @@ static void ttm_bo_release_list(struct kref *list_kref) if (bo->destroy) bo->destroy(bo); else { - kfree(bo, M_DRM); + kfree(bo); } ttm_mem_global_free(bdev->glob->mem_glob, acc_size); } @@ -1256,7 +1256,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, if (destroy) (*destroy)(bo); else - kfree(bo, M_DRM); + kfree(bo); return -ENOMEM; } @@ -1266,7 +1266,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, if (destroy) (*destroy)(bo); else - kfree(bo, M_DRM); + kfree(bo); ttm_mem_global_free(mem_glob, acc_size); return -EINVAL; } @@ -1565,7 +1565,7 @@ out_no_shrink: vm_page_free(glob->dummy_read_page); */ out_no_drp: - kfree(glob, M_DRM); + kfree(glob); return ret; } EXPORT_SYMBOL(ttm_bo_global_init); diff --git a/sys/dev/drm/ttm/ttm_bo_manager.c b/sys/dev/drm/ttm/ttm_bo_manager.c index c88e715d7f..4cb6e1c58a 100644 --- a/sys/dev/drm/ttm/ttm_bo_manager.c +++ b/sys/dev/drm/ttm/ttm_bo_manager.c @@ -111,7 +111,7 @@ static int ttm_bo_man_init(struct ttm_mem_type_manager *man, ret = drm_mm_init(&rman->mm, 0, p_size); if (ret) { - kfree(rman, M_DRM); + kfree(rman); return ret; } @@ -129,7 +129,7 @@ static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man) if (drm_mm_clean(mm)) { drm_mm_takedown(mm); lockmgr(&rman->lock, LK_RELEASE); - kfree(rman, M_DRM); + kfree(rman); man->priv = NULL; return 0; } diff --git a/sys/dev/drm/ttm/ttm_bo_util.c b/sys/dev/drm/ttm/ttm_bo_util.c index f7cea75f76..51354e5ef4 100644 --- a/sys/dev/drm/ttm/ttm_bo_util.c +++ b/sys/dev/drm/ttm/ttm_bo_util.c @@ -379,7 +379,7 @@ EXPORT_SYMBOL(ttm_bo_move_memcpy); static void ttm_transfered_destroy(struct ttm_buffer_object *bo) { - kfree(bo, M_DRM); + kfree(bo); } /** -- 2.41.0 From 372f6e60d8b5056a2cf692df7645fce9b3b69fc9 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Sun, 25 Jan 2015 13:54:27 +0100 Subject: [PATCH 03/16] file(1): Unbreak buildworld. The issue is the missing definition of wchar_t in (required by POSIX too) which file(1) winds up needing because of new code in this version. The commit 3e581a72263dd3b726387b5dc2399a066511099f fixes it correctly but mkmagic.nx is a build-tool and so uses host includes (which don't have that fix yet at this point). I see no other way to fix this easily right now than just including . This has a wchar_t definition, too. Reported-by: Robin Hahling --- contrib/file/src/file.h | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/file/src/file.h b/contrib/file/src/file.h index 01aa37a6b9..c0c7458df0 100644 --- a/contrib/file/src/file.h +++ b/contrib/file/src/file.h @@ -70,6 +70,7 @@ /* Do this here and now, because struct stat gets re-defined on solaris */ #include #include +#include #define ENABLE_CONDITIONALS -- 2.41.0 From 580564c977f204ff746acc026351c0ee70a04b56 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Sun, 25 Jan 2015 19:33:15 +0100 Subject: [PATCH 04/16] libssh: Silence some redefinition warnings. Taken-from: FreeBSD Submitted-by: Robin Hahling --- crypto/openssh/umac128.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crypto/openssh/umac128.c b/crypto/openssh/umac128.c index 52f9173d7c..628fcf64d2 100644 --- a/crypto/openssh/umac128.c +++ b/crypto/openssh/umac128.c @@ -1,6 +1,13 @@ +/* $FreeBSD: head/crypto/openssh/umac128.c 255767 2013-09-21 21:36:09Z des $ */ #define UMAC_OUTPUT_LEN 16 +#undef umac_ctx +#define umac_ctx umac128_ctx +#undef umac_new #define umac_new umac128_new +#undef umac_update #define umac_update umac128_update +#undef umac_final #define umac_final umac128_final +#undef umac_delete #define umac_delete umac128_delete #include "umac.c" -- 2.41.0 From 9be608cb62307f2d282421fd95f1c0cb5dacca57 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Sun, 25 Jan 2015 20:03:55 +0100 Subject: [PATCH 05/16] libssh: Fix a remaining warning and raise WARNS to 2. --- crypto/openssh/cipher-ctr-mt.c | 2 +- secure/lib/libssh/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/openssh/cipher-ctr-mt.c b/crypto/openssh/cipher-ctr-mt.c index c13ddf0a7f..238b53c132 100644 --- a/crypto/openssh/cipher-ctr-mt.c +++ b/crypto/openssh/cipher-ctr-mt.c @@ -285,7 +285,7 @@ thread_loop(void *x) static int ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, - u_int len) + LIBCRYPTO_EVP_INL_TYPE len) { struct ssh_aes_ctr_ctx *c; struct kq *q, *oldq; diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile index 57c1a48ae9..6bd31884d6 100644 --- a/secure/lib/libssh/Makefile +++ b/secure/lib/libssh/Makefile @@ -27,7 +27,7 @@ SRCS+= bcrypt_pbkdf.c blowfish.c bsd-misc.c explicit_bzero.c \ MAN= moduli.5 -WARNS?= 0 +WARNS?= 2 .include "../../Makefile.ssh.common" .include -- 2.41.0 From 54e479e49d6d6486f5f70a7c20c4f5b07d88dcda Mon Sep 17 00:00:00 2001 From: Robin Hahling Date: Sun, 25 Jan 2015 20:49:14 +0100 Subject: [PATCH 06/16] libssh: remove some unused files --- crypto/openssh/README.DELETED | 9 + crypto/openssh/digest-libc.c | 239 -------- crypto/openssh/openbsd-compat/arc4random.c | 294 ---------- crypto/openssh/openbsd-compat/bsd-setres_id.c | 100 ---- .../openssh/openbsd-compat/chacha_private.h | 222 -------- crypto/openssh/openbsd-compat/getopt.h | 74 --- crypto/openssh/openbsd-compat/getopt_long.c | 532 ------------------ crypto/openssh/openbsd-compat/kludge-fd_set.c | 28 - crypto/openssh/openbsd-compat/strtoull.c | 110 ---- crypto/openssh/sandbox-capsicum.c | 122 ---- 10 files changed, 9 insertions(+), 1721 deletions(-) delete mode 100644 crypto/openssh/digest-libc.c delete mode 100644 crypto/openssh/openbsd-compat/arc4random.c delete mode 100644 crypto/openssh/openbsd-compat/bsd-setres_id.c delete mode 100644 crypto/openssh/openbsd-compat/chacha_private.h delete mode 100644 crypto/openssh/openbsd-compat/getopt.h delete mode 100644 crypto/openssh/openbsd-compat/getopt_long.c delete mode 100644 crypto/openssh/openbsd-compat/kludge-fd_set.c delete mode 100644 crypto/openssh/openbsd-compat/strtoull.c delete mode 100644 crypto/openssh/sandbox-capsicum.c diff --git a/crypto/openssh/README.DELETED b/crypto/openssh/README.DELETED index b185d7d4d4..28190c5c8f 100644 --- a/crypto/openssh/README.DELETED +++ b/crypto/openssh/README.DELETED @@ -15,6 +15,7 @@ config.sub configure configure.ac contrib/ +digest-libc.c fixalgorithms fixpaths fixprogs @@ -26,6 +27,7 @@ moduli.0 nchan.ms nchan2.ms openbsd-compat/Makefile.in +openbsd-compat/arc4random.c openbsd-compat/base64.c openbsd-compat/basename.c openbsd-compat/bindresvport.c @@ -37,18 +39,23 @@ openbsd-compat/bsd-getpeereid.c openbsd-compat/bsd-nextstep.c openbsd-compat/bsd-openpty.c openbsd-compat/bsd-poll.c +openbsd-compat/bsd-setres_id.c openbsd-compat/bsd-snprintf.c openbsd-compat/bsd-statvfs.c openbsd-compat/bsd-waitpid.c +openbsd-compat/chacha_private.h openbsd-compat/daemon.c openbsd-compat/dirname.c openbsd-compat/fake-rfc2553.c openbsd-compat/getcwd.c openbsd-compat/getgrouplist.c +openbsd-compat/getopt.h +openbsd-compat/getopt_long.c openbsd-compat/getrrsetbyname-ldns.c openbsd-compat/inet_aton.c openbsd-compat/inet_ntoa.c openbsd-compat/inet_ntop.c +openbsd-compat/kludge-fd_set.c openbsd-compat/mktemp.c openbsd-compat/port-aix.c openbsd-compat/port-irix.c @@ -73,12 +80,14 @@ openbsd-compat/strsep.c openbsd-compat/strtoll.c openbsd-compat/strtonum.c openbsd-compat/strtoul.c +openbsd-compat/strtoull.c openbsd-compat/vis.c openbsd-compat/vis.h openbsd-compat/xcrypt.c openssh.xml.in opensshd.init.in regress/ +sandbox-capsicum.c sandbox-darwin.c sandbox-null.c sandbox-seccomp-filter.c diff --git a/crypto/openssh/digest-libc.c b/crypto/openssh/digest-libc.c deleted file mode 100644 index 1b4423a05c..0000000000 --- a/crypto/openssh/digest-libc.c +++ /dev/null @@ -1,239 +0,0 @@ -/* $OpenBSD: digest-libc.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */ -/* - * Copyright (c) 2013 Damien Miller - * Copyright (c) 2014 Markus Friedl. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ssherr.h" -#include "sshbuf.h" -#include "digest.h" - -typedef void md_init_fn(void *mdctx); -typedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen); -typedef void md_final_fn(u_int8_t[], void *mdctx); - -struct ssh_digest_ctx { - int alg; - void *mdctx; -}; - -struct ssh_digest { - int id; - const char *name; - size_t block_len; - size_t digest_len; - size_t ctx_len; - md_init_fn *md_init; - md_update_fn *md_update; - md_final_fn *md_final; -}; - -/* NB. Indexed directly by algorithm number */ -const struct ssh_digest digests[SSH_DIGEST_MAX] = { - { - SSH_DIGEST_MD5, - "MD5", - MD5_BLOCK_LENGTH, - MD5_DIGEST_LENGTH, - sizeof(MD5_CTX), - (md_init_fn *) MD5Init, - (md_update_fn *) MD5Update, - (md_final_fn *) MD5Final - }, - { - SSH_DIGEST_RIPEMD160, - "RIPEMD160", - RMD160_BLOCK_LENGTH, - RMD160_DIGEST_LENGTH, - sizeof(RMD160_CTX), - (md_init_fn *) RMD160Init, - (md_update_fn *) RMD160Update, - (md_final_fn *) RMD160Final - }, - { - SSH_DIGEST_SHA1, - "SHA1", - SHA1_BLOCK_LENGTH, - SHA1_DIGEST_LENGTH, - sizeof(SHA1_CTX), - (md_init_fn *) SHA1Init, - (md_update_fn *) SHA1Update, - (md_final_fn *) SHA1Final - }, - { - SSH_DIGEST_SHA256, - "SHA256", - SHA256_BLOCK_LENGTH, - SHA256_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA256Init, - (md_update_fn *) SHA256Update, - (md_final_fn *) SHA256Final - }, - { - SSH_DIGEST_SHA384, - "SHA384", - SHA384_BLOCK_LENGTH, - SHA384_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA384Init, - (md_update_fn *) SHA384Update, - (md_final_fn *) SHA384Final - }, - { - SSH_DIGEST_SHA512, - "SHA512", - SHA512_BLOCK_LENGTH, - SHA512_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA512Init, - (md_update_fn *) SHA512Update, - (md_final_fn *) SHA512Final - } -}; - -static const struct ssh_digest * -ssh_digest_by_alg(int alg) -{ - if (alg < 0 || alg >= SSH_DIGEST_MAX) - return NULL; - if (digests[alg].id != alg) /* sanity */ - return NULL; - return &(digests[alg]); -} - -size_t -ssh_digest_bytes(int alg) -{ - const struct ssh_digest *digest = ssh_digest_by_alg(alg); - - return digest == NULL ? 0 : digest->digest_len; -} - -size_t -ssh_digest_blocksize(struct ssh_digest_ctx *ctx) -{ - const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); - - return digest == NULL ? 0 : digest->block_len; -} - -struct ssh_digest_ctx * -ssh_digest_start(int alg) -{ - const struct ssh_digest *digest = ssh_digest_by_alg(alg); - struct ssh_digest_ctx *ret; - - if (digest == NULL || (ret = calloc(1, sizeof(ret))) == NULL) - return NULL; - if ((ret->mdctx = calloc(1, digest->ctx_len)) == NULL) { - free(ret); - return NULL; - } - ret->alg = alg; - digest->md_init(ret->mdctx); - return ret; -} - -int -ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) -{ - const struct ssh_digest *digest = ssh_digest_by_alg(from->alg); - - if (digest == NULL || from->alg != to->alg) - return SSH_ERR_INVALID_ARGUMENT; - memcpy(to->mdctx, from->mdctx, digest->ctx_len); - return 0; -} - -int -ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) -{ - const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); - - if (digest == NULL) - return SSH_ERR_INVALID_ARGUMENT; - digest->md_update(ctx->mdctx, m, mlen); - return 0; -} - -int -ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b) -{ - return ssh_digest_update(ctx, sshbuf_ptr(b), sshbuf_len(b)); -} - -int -ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) -{ - const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); - - if (digest == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if (dlen > UINT_MAX) - return SSH_ERR_INVALID_ARGUMENT; - if (dlen < digest->digest_len) /* No truncation allowed */ - return SSH_ERR_INVALID_ARGUMENT; - digest->md_final(d, ctx->mdctx); - return 0; -} - -void -ssh_digest_free(struct ssh_digest_ctx *ctx) -{ - const struct ssh_digest *digest; - - if (ctx != NULL) { - digest = ssh_digest_by_alg(ctx->alg); - if (digest) { - explicit_bzero(ctx->mdctx, digest->ctx_len); - free(ctx->mdctx); - explicit_bzero(ctx, sizeof(*ctx)); - free(ctx); - } - } -} - -int -ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) -{ - struct ssh_digest_ctx *ctx = ssh_digest_start(alg); - - if (ctx == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if (ssh_digest_update(ctx, m, mlen) != 0 || - ssh_digest_final(ctx, d, dlen) != 0) - return SSH_ERR_INVALID_ARGUMENT; - ssh_digest_free(ctx); - return 0; -} - -int -ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) -{ - return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); -} diff --git a/crypto/openssh/openbsd-compat/arc4random.c b/crypto/openssh/openbsd-compat/arc4random.c deleted file mode 100644 index 09dbfda164..0000000000 --- a/crypto/openssh/openbsd-compat/arc4random.c +++ /dev/null @@ -1,294 +0,0 @@ -/* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */ - -/* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */ - -/* - * Copyright (c) 1996, David Mazieres - * Copyright (c) 2008, Damien Miller - * Copyright (c) 2013, Markus Friedl - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * ChaCha based random number generator for OpenBSD. - */ - -#include "includes.h" - -#include -#include -#include -#include - -#ifndef HAVE_ARC4RANDOM - -#include -#include - -#include "log.h" - -#define KEYSTREAM_ONLY -#include "chacha_private.h" - -#ifdef __GNUC__ -#define inline __inline -#else /* !__GNUC__ */ -#define inline -#endif /* !__GNUC__ */ - -/* OpenSSH isn't multithreaded */ -#define _ARC4_LOCK() -#define _ARC4_UNLOCK() - -#define KEYSZ 32 -#define IVSZ 8 -#define BLOCKSZ 64 -#define RSBUFSZ (16*BLOCKSZ) -static int rs_initialized; -static pid_t rs_stir_pid; -static chacha_ctx rs; /* chacha context for random keystream */ -static u_char rs_buf[RSBUFSZ]; /* keystream blocks */ -static size_t rs_have; /* valid bytes at end of rs_buf */ -static size_t rs_count; /* bytes till reseed */ - -static inline void _rs_rekey(u_char *dat, size_t datlen); - -static inline void -_rs_init(u_char *buf, size_t n) -{ - if (n < KEYSZ + IVSZ) - return; - chacha_keysetup(&rs, buf, KEYSZ * 8, 0); - chacha_ivsetup(&rs, buf + KEYSZ); -} - -static void -_rs_stir(void) -{ - u_char rnd[KEYSZ + IVSZ]; - - if (RAND_bytes(rnd, sizeof(rnd)) <= 0) - fatal("Couldn't obtain random bytes (error %ld)", - ERR_get_error()); - - if (!rs_initialized) { - rs_initialized = 1; - _rs_init(rnd, sizeof(rnd)); - } else - _rs_rekey(rnd, sizeof(rnd)); - explicit_bzero(rnd, sizeof(rnd)); - - /* invalidate rs_buf */ - rs_have = 0; - memset(rs_buf, 0, RSBUFSZ); - - rs_count = 1600000; -} - -static inline void -_rs_stir_if_needed(size_t len) -{ - pid_t pid = getpid(); - - if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) { - rs_stir_pid = pid; - _rs_stir(); - } else - rs_count -= len; -} - -static inline void -_rs_rekey(u_char *dat, size_t datlen) -{ -#ifndef KEYSTREAM_ONLY - memset(rs_buf, 0,RSBUFSZ); -#endif - /* fill rs_buf with the keystream */ - chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ); - /* mix in optional user provided data */ - if (dat) { - size_t i, m; - - m = MIN(datlen, KEYSZ + IVSZ); - for (i = 0; i < m; i++) - rs_buf[i] ^= dat[i]; - } - /* immediately reinit for backtracking resistance */ - _rs_init(rs_buf, KEYSZ + IVSZ); - memset(rs_buf, 0, KEYSZ + IVSZ); - rs_have = RSBUFSZ - KEYSZ - IVSZ; -} - -static inline void -_rs_random_buf(void *_buf, size_t n) -{ - u_char *buf = (u_char *)_buf; - size_t m; - - _rs_stir_if_needed(n); - while (n > 0) { - if (rs_have > 0) { - m = MIN(n, rs_have); - memcpy(buf, rs_buf + RSBUFSZ - rs_have, m); - memset(rs_buf + RSBUFSZ - rs_have, 0, m); - buf += m; - n -= m; - rs_have -= m; - } - if (rs_have == 0) - _rs_rekey(NULL, 0); - } -} - -static inline void -_rs_random_u32(u_int32_t *val) -{ - _rs_stir_if_needed(sizeof(*val)); - if (rs_have < sizeof(*val)) - _rs_rekey(NULL, 0); - memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val)); - memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val)); - rs_have -= sizeof(*val); - return; -} - -void -arc4random_stir(void) -{ - _ARC4_LOCK(); - _rs_stir(); - _ARC4_UNLOCK(); -} - -void -arc4random_addrandom(u_char *dat, int datlen) -{ - int m; - - _ARC4_LOCK(); - if (!rs_initialized) - _rs_stir(); - while (datlen > 0) { - m = MIN(datlen, KEYSZ + IVSZ); - _rs_rekey(dat, m); - dat += m; - datlen -= m; - } - _ARC4_UNLOCK(); -} - -u_int32_t -arc4random(void) -{ - u_int32_t val; - - _ARC4_LOCK(); - _rs_random_u32(&val); - _ARC4_UNLOCK(); - return val; -} - -/* - * If we are providing arc4random, then we can provide a more efficient - * arc4random_buf(). - */ -# ifndef HAVE_ARC4RANDOM_BUF -void -arc4random_buf(void *buf, size_t n) -{ - _ARC4_LOCK(); - _rs_random_buf(buf, n); - _ARC4_UNLOCK(); -} -# endif /* !HAVE_ARC4RANDOM_BUF */ -#endif /* !HAVE_ARC4RANDOM */ - -/* arc4random_buf() that uses platform arc4random() */ -#if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) -void -arc4random_buf(void *_buf, size_t n) -{ - size_t i; - u_int32_t r = 0; - char *buf = (char *)_buf; - - for (i = 0; i < n; i++) { - if (i % 4 == 0) - r = arc4random(); - buf[i] = r & 0xff; - r >>= 8; - } - explicit_bzero(&r, sizeof(r)); -} -#endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */ - -#ifndef HAVE_ARC4RANDOM_UNIFORM -/* - * Calculate a uniformly distributed random number less than upper_bound - * avoiding "modulo bias". - * - * Uniformity is achieved by generating new random numbers until the one - * returned is outside the range [0, 2**32 % upper_bound). This - * guarantees the selected random number will be inside - * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) - * after reduction modulo upper_bound. - */ -u_int32_t -arc4random_uniform(u_int32_t upper_bound) -{ - u_int32_t r, min; - - if (upper_bound < 2) - return 0; - - /* 2**32 % x == (2**32 - x) % x */ - min = -upper_bound % upper_bound; - - /* - * This could theoretically loop forever but each retry has - * p > 0.5 (worst case, usually far better) of selecting a - * number inside the range we need, so it should rarely need - * to re-roll. - */ - for (;;) { - r = arc4random(); - if (r >= min) - break; - } - - return r % upper_bound; -} -#endif /* !HAVE_ARC4RANDOM_UNIFORM */ - -#if 0 -/*-------- Test code for i386 --------*/ -#include -#include -int -main(int argc, char **argv) -{ - const int iter = 1000000; - int i; - pctrval v; - - v = rdtsc(); - for (i = 0; i < iter; i++) - arc4random(); - v = rdtsc() - v; - v /= iter; - - printf("%qd cycles\n", v); - exit(0); -} -#endif diff --git a/crypto/openssh/openbsd-compat/bsd-setres_id.c b/crypto/openssh/openbsd-compat/bsd-setres_id.c deleted file mode 100644 index 018bde8c76..0000000000 --- a/crypto/openssh/openbsd-compat/bsd-setres_id.c +++ /dev/null @@ -1,100 +0,0 @@ -/* $Id: bsd-setres_id.c,v 1.2 2013/12/07 21:23:09 djm Exp $ */ - -/* - * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include - -#include -#include -#include - -#include "log.h" - -#if !defined(HAVE_SETRESGID) || defined(BROKEN_SETRESGID) -int -setresgid(gid_t rgid, gid_t egid, gid_t sgid) -{ - int ret = 0, saved_errno; - - if (rgid != sgid) { - errno = ENOSYS; - return -1; - } -#if defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID) - if (setregid(rgid, egid) < 0) { - saved_errno = errno; - error("setregid %u: %.100s", rgid, strerror(errno)); - errno = saved_errno; - ret = -1; - } -#else - if (setegid(egid) < 0) { - saved_errno = errno; - error("setegid %u: %.100s", (u_int)egid, strerror(errno)); - errno = saved_errno; - ret = -1; - } - if (setgid(rgid) < 0) { - saved_errno = errno; - error("setgid %u: %.100s", rgid, strerror(errno)); - errno = saved_errno; - ret = -1; - } -#endif - return ret; -} -#endif - -#if !defined(HAVE_SETRESUID) || defined(BROKEN_SETRESUID) -int -setresuid(uid_t ruid, uid_t euid, uid_t suid) -{ - int ret = 0, saved_errno; - - if (ruid != suid) { - errno = ENOSYS; - return -1; - } -#if defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID) - if (setreuid(ruid, euid) < 0) { - saved_errno = errno; - error("setreuid %u: %.100s", ruid, strerror(errno)); - errno = saved_errno; - ret = -1; - } -#else - -# ifndef SETEUID_BREAKS_SETUID - if (seteuid(euid) < 0) { - saved_errno = errno; - error("seteuid %u: %.100s", euid, strerror(errno)); - errno = saved_errno; - ret = -1; - } -# endif - if (setuid(ruid) < 0) { - saved_errno = errno; - error("setuid %u: %.100s", ruid, strerror(errno)); - errno = saved_errno; - ret = -1; - } -#endif - return ret; -} -#endif diff --git a/crypto/openssh/openbsd-compat/chacha_private.h b/crypto/openssh/openbsd-compat/chacha_private.h deleted file mode 100644 index 7c3680fa6d..0000000000 --- a/crypto/openssh/openbsd-compat/chacha_private.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -chacha-merged.c version 20080118 -D. J. Bernstein -Public domain. -*/ - -/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ - -typedef unsigned char u8; -typedef unsigned int u32; - -typedef struct -{ - u32 input[16]; /* could be compressed */ -} chacha_ctx; - -#define U8C(v) (v##U) -#define U32C(v) (v##U) - -#define U8V(v) ((u8)(v) & U8C(0xFF)) -#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) - -#define ROTL32(v, n) \ - (U32V((v) << (n)) | ((v) >> (32 - (n)))) - -#define U8TO32_LITTLE(p) \ - (((u32)((p)[0]) ) | \ - ((u32)((p)[1]) << 8) | \ - ((u32)((p)[2]) << 16) | \ - ((u32)((p)[3]) << 24)) - -#define U32TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - } while (0) - -#define ROTATE(v,c) (ROTL32(v,c)) -#define XOR(v,w) ((v) ^ (w)) -#define PLUS(v,w) (U32V((v) + (w))) -#define PLUSONE(v) (PLUS((v),1)) - -#define QUARTERROUND(a,b,c,d) \ - a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ - a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); - -static const char sigma[16] = "expand 32-byte k"; -static const char tau[16] = "expand 16-byte k"; - -static void -chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) -{ - const char *constants; - - x->input[4] = U8TO32_LITTLE(k + 0); - x->input[5] = U8TO32_LITTLE(k + 4); - x->input[6] = U8TO32_LITTLE(k + 8); - x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ - k += 16; - constants = sigma; - } else { /* kbits == 128 */ - constants = tau; - } - x->input[8] = U8TO32_LITTLE(k + 0); - x->input[9] = U8TO32_LITTLE(k + 4); - x->input[10] = U8TO32_LITTLE(k + 8); - x->input[11] = U8TO32_LITTLE(k + 12); - x->input[0] = U8TO32_LITTLE(constants + 0); - x->input[1] = U8TO32_LITTLE(constants + 4); - x->input[2] = U8TO32_LITTLE(constants + 8); - x->input[3] = U8TO32_LITTLE(constants + 12); -} - -static void -chacha_ivsetup(chacha_ctx *x,const u8 *iv) -{ - x->input[12] = 0; - x->input[13] = 0; - x->input[14] = U8TO32_LITTLE(iv + 0); - x->input[15] = U8TO32_LITTLE(iv + 4); -} - -static void -chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) -{ - u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; - u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; - u8 *ctarget = NULL; - u8 tmp[64]; - u_int i; - - if (!bytes) return; - - j0 = x->input[0]; - j1 = x->input[1]; - j2 = x->input[2]; - j3 = x->input[3]; - j4 = x->input[4]; - j5 = x->input[5]; - j6 = x->input[6]; - j7 = x->input[7]; - j8 = x->input[8]; - j9 = x->input[9]; - j10 = x->input[10]; - j11 = x->input[11]; - j12 = x->input[12]; - j13 = x->input[13]; - j14 = x->input[14]; - j15 = x->input[15]; - - for (;;) { - if (bytes < 64) { - for (i = 0;i < bytes;++i) tmp[i] = m[i]; - m = tmp; - ctarget = c; - c = tmp; - } - x0 = j0; - x1 = j1; - x2 = j2; - x3 = j3; - x4 = j4; - x5 = j5; - x6 = j6; - x7 = j7; - x8 = j8; - x9 = j9; - x10 = j10; - x11 = j11; - x12 = j12; - x13 = j13; - x14 = j14; - x15 = j15; - for (i = 20;i > 0;i -= 2) { - QUARTERROUND( x0, x4, x8,x12) - QUARTERROUND( x1, x5, x9,x13) - QUARTERROUND( x2, x6,x10,x14) - QUARTERROUND( x3, x7,x11,x15) - QUARTERROUND( x0, x5,x10,x15) - QUARTERROUND( x1, x6,x11,x12) - QUARTERROUND( x2, x7, x8,x13) - QUARTERROUND( x3, x4, x9,x14) - } - x0 = PLUS(x0,j0); - x1 = PLUS(x1,j1); - x2 = PLUS(x2,j2); - x3 = PLUS(x3,j3); - x4 = PLUS(x4,j4); - x5 = PLUS(x5,j5); - x6 = PLUS(x6,j6); - x7 = PLUS(x7,j7); - x8 = PLUS(x8,j8); - x9 = PLUS(x9,j9); - x10 = PLUS(x10,j10); - x11 = PLUS(x11,j11); - x12 = PLUS(x12,j12); - x13 = PLUS(x13,j13); - x14 = PLUS(x14,j14); - x15 = PLUS(x15,j15); - -#ifndef KEYSTREAM_ONLY - x0 = XOR(x0,U8TO32_LITTLE(m + 0)); - x1 = XOR(x1,U8TO32_LITTLE(m + 4)); - x2 = XOR(x2,U8TO32_LITTLE(m + 8)); - x3 = XOR(x3,U8TO32_LITTLE(m + 12)); - x4 = XOR(x4,U8TO32_LITTLE(m + 16)); - x5 = XOR(x5,U8TO32_LITTLE(m + 20)); - x6 = XOR(x6,U8TO32_LITTLE(m + 24)); - x7 = XOR(x7,U8TO32_LITTLE(m + 28)); - x8 = XOR(x8,U8TO32_LITTLE(m + 32)); - x9 = XOR(x9,U8TO32_LITTLE(m + 36)); - x10 = XOR(x10,U8TO32_LITTLE(m + 40)); - x11 = XOR(x11,U8TO32_LITTLE(m + 44)); - x12 = XOR(x12,U8TO32_LITTLE(m + 48)); - x13 = XOR(x13,U8TO32_LITTLE(m + 52)); - x14 = XOR(x14,U8TO32_LITTLE(m + 56)); - x15 = XOR(x15,U8TO32_LITTLE(m + 60)); -#endif - - j12 = PLUSONE(j12); - if (!j12) { - j13 = PLUSONE(j13); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - - U32TO8_LITTLE(c + 0,x0); - U32TO8_LITTLE(c + 4,x1); - U32TO8_LITTLE(c + 8,x2); - U32TO8_LITTLE(c + 12,x3); - U32TO8_LITTLE(c + 16,x4); - U32TO8_LITTLE(c + 20,x5); - U32TO8_LITTLE(c + 24,x6); - U32TO8_LITTLE(c + 28,x7); - U32TO8_LITTLE(c + 32,x8); - U32TO8_LITTLE(c + 36,x9); - U32TO8_LITTLE(c + 40,x10); - U32TO8_LITTLE(c + 44,x11); - U32TO8_LITTLE(c + 48,x12); - U32TO8_LITTLE(c + 52,x13); - U32TO8_LITTLE(c + 56,x14); - U32TO8_LITTLE(c + 60,x15); - - if (bytes <= 64) { - if (bytes < 64) { - for (i = 0;i < bytes;++i) ctarget[i] = c[i]; - } - x->input[12] = j12; - x->input[13] = j13; - return; - } - bytes -= 64; - c += 64; -#ifndef KEYSTREAM_ONLY - m += 64; -#endif - } -} diff --git a/crypto/openssh/openbsd-compat/getopt.h b/crypto/openssh/openbsd-compat/getopt.h deleted file mode 100644 index 8eb12447ed..0000000000 --- a/crypto/openssh/openbsd-compat/getopt.h +++ /dev/null @@ -1,74 +0,0 @@ -/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */ -/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _GETOPT_H_ -#define _GETOPT_H_ - -/* - * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions - */ -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -struct option { - /* name of long option */ - const char *name; - /* - * one of no_argument, required_argument, and optional_argument: - * whether option takes an argument - */ - int has_arg; - /* if not NULL, set *flag to val when option found */ - int *flag; - /* if flag not NULL, value to set *flag to; else return value */ - int val; -}; - -int getopt_long(int, char * const *, const char *, - const struct option *, int *); -int getopt_long_only(int, char * const *, const char *, - const struct option *, int *); -#ifndef _GETOPT_DEFINED_ -#define _GETOPT_DEFINED_ -int getopt(int, char * const *, const char *); -int getsubopt(char **, char * const *, char **); - -extern char *optarg; /* getopt(3) external variables */ -extern int opterr; -extern int optind; -extern int optopt; -extern int optreset; -extern char *suboptarg; /* getsubopt(3) external variable */ -#endif - -#endif /* !_GETOPT_H_ */ diff --git a/crypto/openssh/openbsd-compat/getopt_long.c b/crypto/openssh/openbsd-compat/getopt_long.c deleted file mode 100644 index e289474305..0000000000 --- a/crypto/openssh/openbsd-compat/getopt_long.c +++ /dev/null @@ -1,532 +0,0 @@ -/* $OpenBSD: getopt_long.c,v 1.25 2011/03/05 22:10:11 guenther Exp $ */ -/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ - -/* - * Copyright (c) 2002 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt_long.c */ -#include "includes.h" - -#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) - -/* - * Some defines to make it easier to keep the code in sync with upstream. - * getopt opterr optind optopt optreset optarg are all in defines.h which is - * pulled in by includes.h. - */ -#define warnx logit - -#if 0 -#include -#include -#endif -#include -#include -#include -#include - -#include "log.h" - -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt = '?'; /* character checked for validity */ -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -#define PRINT_ERROR ((opterr) && (*options != ':')) - -#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ -#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ -#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ - -/* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 - -#define EMSG "" - -static int getopt_internal(int, char * const *, const char *, - const struct option *, int *, int); -static int parse_long_options(char * const *, const char *, - const struct option *, int *, int); -static int gcd(int, int); -static void permute_args(int, int, int, char * const *); - -static char *place = EMSG; /* option letter processing */ - -/* XXX: set optreset to 1 rather than these two */ -static int nonopt_start = -1; /* first non option argument (for permute) */ -static int nonopt_end = -1; /* first option after non options (for permute) */ - -/* Error messages */ -static const char recargchar[] = "option requires an argument -- %c"; -static const char recargstring[] = "option requires an argument -- %s"; -static const char ambig[] = "ambiguous option -- %.*s"; -static const char noarg[] = "option doesn't take an argument -- %.*s"; -static const char illoptchar[] = "unknown option -- %c"; -static const char illoptstring[] = "unknown option -- %s"; - -/* - * Compute the greatest common divisor of a and b. - */ -static int -gcd(int a, int b) -{ - int c; - - c = a % b; - while (c != 0) { - a = b; - b = c; - c = a % b; - } - - return (b); -} - -/* - * Exchange the block from nonopt_start to nonopt_end with the block - * from nonopt_end to opt_end (keeping the same order of arguments - * in each block). - */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) -{ - int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; - char *swap; - - /* - * compute lengths of blocks and number and size of cycles - */ - nnonopts = panonopt_end - panonopt_start; - nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); - cyclelen = (opt_end - panonopt_start) / ncycle; - - for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; - pos = cstart; - for (j = 0; j < cyclelen; j++) { - if (pos >= panonopt_end) - pos -= nnonopts; - else - pos += nopts; - swap = nargv[pos]; - /* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; - /* LINTED const cast */ - ((char **)nargv)[cstart] = swap; - } - } -} - -/* - * parse_long_options -- - * Parse long options in argc/argv argument vector. - * Returns -1 if short_too is set and the option does not match long_options. - */ -static int -parse_long_options(char * const *nargv, const char *options, - const struct option *long_options, int *idx, int short_too) -{ - char *current_argv, *has_equal; - size_t current_argv_len; - int i, match; - - current_argv = place; - match = -1; - - optind++; - - if ((has_equal = strchr(current_argv, '=')) != NULL) { - /* argument found (--option=arg) */ - current_argv_len = has_equal - current_argv; - has_equal++; - } else - current_argv_len = strlen(current_argv); - - for (i = 0; long_options[i].name; i++) { - /* find matching long option */ - if (strncmp(current_argv, long_options[i].name, - current_argv_len)) - continue; - - if (strlen(long_options[i].name) == current_argv_len) { - /* exact match */ - match = i; - break; - } - /* - * If this is a known short option, don't allow - * a partial match of a single character. - */ - if (short_too && current_argv_len == 1) - continue; - - if (match == -1) /* partial match */ - match = i; - else { - /* ambiguous abbreviation */ - if (PRINT_ERROR) - warnx(ambig, (int)current_argv_len, - current_argv); - optopt = 0; - return (BADCH); - } - } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument - && has_equal) { - if (PRINT_ERROR) - warnx(noarg, (int)current_argv_len, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - return (BADARG); - } - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { - if (has_equal) - optarg = has_equal; - else if (long_options[match].has_arg == - required_argument) { - /* - * optional argument doesn't use next nargv - */ - optarg = nargv[optind++]; - } - } - if ((long_options[match].has_arg == required_argument) - && (optarg == NULL)) { - /* - * Missing argument; leading ':' indicates no error - * should be generated. - */ - if (PRINT_ERROR) - warnx(recargstring, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - --optind; - return (BADARG); - } - } else { /* unknown option */ - if (short_too) { - --optind; - return (-1); - } - if (PRINT_ERROR) - warnx(illoptstring, current_argv); - optopt = 0; - return (BADCH); - } - if (idx) - *idx = match; - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - return (0); - } else - return (long_options[match].val); -} - -/* - * getopt_internal -- - * Parse argc/argv argument vector. Called by user level routines. - */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx, int flags) -{ - char *oli; /* option letter list index */ - int optchar, short_too; - static int posixly_correct = -1; - - if (options == NULL) - return (-1); - - /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ - if (optind == 0) - optind = optreset = 1; - - /* - * Disable GNU extensions if POSIXLY_CORRECT is set or options - * string begins with a '+'. - */ - if (posixly_correct == -1 || optreset) - posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); - if (*options == '-') - flags |= FLAG_ALLARGS; - else if (posixly_correct || *options == '+') - flags &= ~FLAG_PERMUTE; - if (*options == '+' || *options == '-') - options++; - - optarg = NULL; - if (optreset) - nonopt_start = nonopt_end = -1; -start: - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc) { /* end of argument vector */ - place = EMSG; - if (nonopt_end != -1) { - /* do permutation, if we have to */ - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - else if (nonopt_start != -1) { - /* - * If we skipped non-options, set optind - * to the first of them. - */ - optind = nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - if (*(place = nargv[optind]) != '-' || - (place[1] == '\0' && strchr(options, '-') == NULL)) { - place = EMSG; /* found non-option */ - if (flags & FLAG_ALLARGS) { - /* - * GNU extension: - * return non-option as argument to option 1 - */ - optarg = nargv[optind++]; - return (INORDER); - } - if (!(flags & FLAG_PERMUTE)) { - /* - * If no permutation wanted, stop parsing - * at first non-option. - */ - return (-1); - } - /* do permutation */ - if (nonopt_start == -1) - nonopt_start = optind; - else if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - nonopt_start = optind - - (nonopt_end - nonopt_start); - nonopt_end = -1; - } - optind++; - /* process next argument */ - goto start; - } - if (nonopt_start != -1 && nonopt_end == -1) - nonopt_end = optind; - - /* - * If we have "-" do nothing, if "--" we are done. - */ - if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { - optind++; - place = EMSG; - /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - } - - /* - * Check long options if: - * 1) we were passed some - * 2) the arg is not just "-" - * 3) either the arg starts with -- we are getopt_long_only() - */ - if (long_options != NULL && place != nargv[optind] && - (*place == '-' || (flags & FLAG_LONGONLY))) { - short_too = 0; - if (*place == '-') - place++; /* --foo long option */ - else if (*place != ':' && strchr(options, *place) != NULL) - short_too = 1; /* could be short option too */ - - optchar = parse_long_options(nargv, options, long_options, - idx, short_too); - if (optchar != -1) { - place = EMSG; - return (optchar); - } - } - - if ((optchar = (int)*place++) == (int)':' || - (optchar == (int)'-' && *place != '\0') || - (oli = strchr(options, optchar)) == NULL) { - /* - * If the user specified "-" and '-' isn't listed in - * options, return -1 (non-option) as per POSIX. - * Otherwise, it is an unknown option character (or ':'). - */ - if (optchar == (int)'-' && *place == '\0') - return (-1); - if (!*place) - ++optind; - if (PRINT_ERROR) - warnx(illoptchar, optchar); - optopt = optchar; - return (BADCH); - } - if (long_options != NULL && optchar == 'W' && oli[1] == ';') { - /* -W long-option */ - if (*place) /* no space */ - /* NOTHING */; - else if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else /* white space */ - place = nargv[optind]; - optchar = parse_long_options(nargv, options, long_options, - idx, 0); - place = EMSG; - return (optchar); - } - if (*++oli != ':') { /* doesn't take argument */ - if (!*place) - ++optind; - } else { /* takes (optional) argument */ - optarg = NULL; - if (*place) /* no white space */ - optarg = place; - else if (oli[1] != ':') { /* arg not optional */ - if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else - optarg = nargv[optind]; - } - place = EMSG; - ++optind; - } - /* dump back option letter */ - return (optchar); -} - -/* - * getopt -- - * Parse argc/argv argument vector. - * - * [eventually this will replace the BSD getopt] - */ -int -getopt(int nargc, char * const *nargv, const char *options) -{ - - /* - * We don't pass FLAG_PERMUTE to getopt_internal() since - * the BSD getopt(3) (unlike GNU) has never done this. - * - * Furthermore, since many privileged programs call getopt() - * before dropping privileges it makes sense to keep things - * as simple (and bug-free) as possible. - */ - return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); -} - -#if 0 -/* - * getopt_long -- - * Parse argc/argv argument vector. - */ -int -getopt_long(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE)); -} - -/* - * getopt_long_only -- - * Parse argc/argv argument vector. - */ -int -getopt_long_only(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE|FLAG_LONGONLY)); -} -#endif - -#endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */ diff --git a/crypto/openssh/openbsd-compat/kludge-fd_set.c b/crypto/openssh/openbsd-compat/kludge-fd_set.c deleted file mode 100644 index 6c2ffb64bd..0000000000 --- a/crypto/openssh/openbsd-compat/kludge-fd_set.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Placed in the public domain. */ - -/* - * _FORTIFY_SOURCE includes a misguided check for FD_SET(n)/FD_ISSET(b) - * where n > FD_SETSIZE. This breaks OpenSSH and other programs that - * explicitly allocate fd_sets. To avoid this, we wrap FD_SET in a - * function compiled without _FORTIFY_SOURCE. - */ - -#include "config.h" - -#if defined(HAVE_FEATURES_H) && defined(_FORTIFY_SOURCE) -# include -# if defined(__GNU_LIBRARY__) && defined(__GLIBC_PREREQ) -# if __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) -# undef _FORTIFY_SOURCE -# undef __USE_FORTIFY_LEVEL -# include -void kludge_FD_SET(int n, fd_set *set) { - FD_SET(n, set); -} -int kludge_FD_ISSET(int n, fd_set *set) { - return FD_ISSET(n, set); -} -# endif /* __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) */ -# endif /* __GNU_LIBRARY__ && __GLIBC_PREREQ */ -#endif /* HAVE_FEATURES_H && _FORTIFY_SOURCE */ - diff --git a/crypto/openssh/openbsd-compat/strtoull.c b/crypto/openssh/openbsd-compat/strtoull.c deleted file mode 100644 index f7c818c527..0000000000 --- a/crypto/openssh/openbsd-compat/strtoull.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $OpenBSD: strtoull.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ -/*- - * Copyright (c) 1992 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* OPENBSD ORIGINAL: lib/libc/stdlib/strtoull.c */ - -#include "includes.h" -#ifndef HAVE_STRTOULL - -#include - -#include -#include -#include -#include - -/* - * Convert a string to an unsigned long long. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long long -strtoull(const char *nptr, char **endptr, int base) -{ - const char *s; - unsigned long long acc, cutoff; - int c; - int neg, any, cutlim; - - /* - * See strtoq for comments as to the logic used. - */ - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - cutoff = ULLONG_MAX / (unsigned long long)base; - cutlim = ULLONG_MAX % (unsigned long long)base; - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = ULLONG_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= (unsigned long long)base; - acc += c; - } - } - if (neg && any > 0) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} -#endif /* !HAVE_STRTOULL */ diff --git a/crypto/openssh/sandbox-capsicum.c b/crypto/openssh/sandbox-capsicum.c deleted file mode 100644 index 655f0d2178..0000000000 --- a/crypto/openssh/sandbox-capsicum.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2011 Dag-Erling Smorgrav - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#ifdef SANDBOX_CAPSICUM - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "monitor.h" -#include "ssh-sandbox.h" -#include "xmalloc.h" - -/* - * Capsicum sandbox that sets zero nfiles, nprocs and filesize rlimits, - * limits rights on stdout, stdin, stderr, monitor and switches to - * capability mode. - */ - -struct ssh_sandbox { - struct monitor *monitor; - pid_t child_pid; -}; - -struct ssh_sandbox * -ssh_sandbox_init(struct monitor *monitor) -{ - struct ssh_sandbox *box; - - /* - * Strictly, we don't need to maintain any state here but we need - * to return non-NULL to satisfy the API. - */ - debug3("%s: preparing capsicum sandbox", __func__); - box = xcalloc(1, sizeof(*box)); - box->monitor = monitor; - box->child_pid = 0; - - return box; -} - -void -ssh_sandbox_child(struct ssh_sandbox *box) -{ - struct rlimit rl_zero; - cap_rights_t rights; - - rl_zero.rlim_cur = rl_zero.rlim_max = 0; - - if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) - fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", - __func__, strerror(errno)); -#ifndef SANDBOX_SKIP_RLIMIT_NOFILE - if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) - fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", - __func__, strerror(errno)); -#endif - if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) - fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", - __func__, strerror(errno)); - - cap_rights_init(&rights); - - if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) - fatal("can't limit stdin: %m"); - if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) - fatal("can't limit stdout: %m"); - if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) - fatal("can't limit stderr: %m"); - - cap_rights_init(&rights, CAP_READ, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 && - errno != ENOSYS) - fatal("%s: failed to limit the network socket", __func__); - cap_rights_init(&rights, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 && - errno != ENOSYS) - fatal("%s: failed to limit the logging socket", __func__); - if (cap_enter() < 0 && errno != ENOSYS) - fatal("%s: failed to enter capability mode", __func__); - -} - -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - -#endif /* SANDBOX_CAPSICUM */ -- 2.41.0 From 4923debce6246628ba6c3362b5a281ba2de03876 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 25 Jan 2015 14:00:28 -0800 Subject: [PATCH 07/16] openssh: Fix version stuff. The previous code was trying to get too fancy by trying to use configuration options in places where those options weren't sent yet. Fix a case in sshconnect.c where version_addendum wasn't being used. Update README.DRAGONFLY to reflect the latest upgrade instructions. --- crypto/openssh/README.DRAGONFLY | 5 +++-- crypto/openssh/ssh.c | 18 +++++------------- crypto/openssh/sshconnect.c | 13 ++++++------- crypto/openssh/sshd.c | 7 ++++--- crypto/openssh/version.h | 2 +- 5 files changed, 19 insertions(+), 26 deletions(-) diff --git a/crypto/openssh/README.DRAGONFLY b/crypto/openssh/README.DRAGONFLY index b383ee7341..b890d98eb9 100644 --- a/crypto/openssh/README.DRAGONFLY +++ b/crypto/openssh/README.DRAGONFLY @@ -5,9 +5,10 @@ A list of deleted files is in README.DELETED. Upgrading notes: ./configure --prefix=/usr --sysconfdir=/etc/ssh --with-sandbox=rlimit \ - --with-pam --with-tcp-wrappers --with-libedit --with-ssl-engine + --with-pam --with-libedit --with-ssl-engine -Update config.h and version.h in secure/lib/libssh. +Update SSH_VERSION_DRAGONFLY in version.h. +Update config.h in secure/lib/libssh. Update ssh{,d}_config and ssh{,d}_config.5. Update ssh_namespace.h diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index b6a0cb1e4d..9aeaf49149 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -636,22 +636,14 @@ main(int ac, char **av) } break; case 'V': - if (options.version_addendum && - *options.version_addendum != '\0') - fprintf(stderr, "%s%s %s, %s\n", SSH_RELEASE, - options.hpn_disabled ? "" : SSH_VERSION_HPN, - options.version_addendum, - SSLeay_version(SSLEAY_VERSION)); - else - fprintf(stderr, "%s%s, %s\n", - SSH_RELEASE, - options.hpn_disabled ? "" : SSH_VERSION_HPN, + fprintf(stderr, "%s%s %s, %s\n", SSH_RELEASE, + SSH_VERSION_HPN, SSH_VERSION_DRAGONFLY, #ifdef WITH_OPENSSL - SSLeay_version(SSLEAY_VERSION) + SSLeay_version(SSLEAY_VERSION) #else - "without OpenSSL" + "without OpenSSL" #endif - ); + ); if (opt == 'V') exit(0); break; diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index 7900919f8a..f10810190f 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -548,13 +548,12 @@ static void send_client_banner(int connection_out, int minor1) { /* Send our own protocol version identification. */ - if (compat20) { - xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE); - } else { - xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", - PROTOCOL_MAJOR_1, minor1, SSH_RELEASE); - } + xasprintf(&client_version_string, "SSH-%d.%d-%.100s%s%s%s%s", + compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, + compat20 ? PROTOCOL_MINOR_2 : minor1, + SSH_RELEASE, options.hpn_disabled ? "" : SSH_VERSION_HPN, + *options.version_addendum == '\0' ? "" : " ", + options.version_addendum, compat20 ? "\r\n" : "\n"); if (roaming_atomicio(vwrite, connection_out, client_version_string, strlen(client_version_string)) != strlen(client_version_string)) fatal("write: %.100s", strerror(errno)); diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 3de6f7f841..39fb4b877b 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -435,8 +435,9 @@ sshd_exchange_identification(int sock_in, int sock_out) minor = PROTOCOL_MINOR_1; } - xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", + xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s%s", major, minor, SSH_RELEASE, + options.hpn_disabled ? "" : SSH_VERSION_HPN, *options.version_addendum == '\0' ? "" : " ", options.version_addendum, newline); @@ -940,8 +941,8 @@ drop_connection(int startups) static void usage(void) { - fprintf(stderr, "%s, %s\n", - SSH_RELEASE, + fprintf(stderr, "%s%s %s, %s\n", + SSH_RELEASE, SSH_VERSION_HPN, SSH_VERSION_DRAGONFLY, #ifdef WITH_OPENSSL SSLeay_version(SSLEAY_VERSION) #else diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index abef40cfac..83a605c403 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -3,7 +3,7 @@ #define SSH_VERSION "OpenSSH_6.7" #define SSH_PORTABLE "p1" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE #define SSH_VERSION_DRAGONFLY "DragonFly-20050123" #define SSH_VERSION_HPN "_hpn14v5" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_VERSION_HPN -- 2.41.0 From 6e9a60839b39b434df2012ba2687ef08e4340531 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Mon, 26 Jan 2015 13:41:23 +0100 Subject: [PATCH 08/16] pxeboot.8: Small adjustments. --- sys/boot/pc32/pxeldr/pxeboot.8 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/boot/pc32/pxeldr/pxeboot.8 b/sys/boot/pc32/pxeldr/pxeboot.8 index cc31041cb8..73cd8b9838 100644 --- a/sys/boot/pc32/pxeldr/pxeboot.8 +++ b/sys/boot/pc32/pxeldr/pxeboot.8 @@ -73,12 +73,11 @@ subnet 10.0.0.0 netmask 255.255.255.0 { .Ed .Nm -defaults to a conservative 1024 byte NFS data packet. This may be changed -by setting the +defaults to a conservative 1024 byte NFS data packet. +This may be changed by setting the .Va nfs.read_size variable in -.Pa /boot/loader.conf -.. +.Pa /boot/loader.conf . Valid values range from 1024 to 4096 bytes. .Pp .Nm -- 2.41.0 From e03628b9ba52d59e76532075b13d6499037477af Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 26 Jan 2015 15:45:11 -0800 Subject: [PATCH 09/16] kernel - limit backtrace-on-panic to 6 call levels * Limit the backtrace-on-panic to 6 call levels to try to keep more information leading up to the crash (such as the panic message) on row-limited consoles. --- sys/kern/kern_shutdown.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index e9eb01a588..49d3b0cda1 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -805,10 +805,13 @@ panic(const char *fmt, ...) * Enter the debugger or fall through & dump. Entering the * debugger will stop cpus. If not entering the debugger stop * cpus here. + * + * Limit the trace history to leave more panic data on a + * potentially row-limited console. */ #if defined(DDB) if (newpanic && trace_on_panic) - print_backtrace(-1); + print_backtrace(6); if (debugger_on_panic) Debugger("panic"); else -- 2.41.0 From 8ec5b2c920b2e0bb7332e15b9c3dc910b1d6284c Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 26 Jan 2015 15:46:25 -0800 Subject: [PATCH 10/16] kernel - Add swap-backed kernel memory allocator API * Add kmem_alloc_swapbacked() and kmem_free_swapbacked(). Allocates kernel memory which is pageable and backed by swap. --- sys/vm/vm_extern.h | 2 ++ sys/vm/vm_kern.c | 55 +++++++++++++++++++++++++++++++++++++++++++++- sys/vm/vm_kern.h | 14 ++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 4b6ebf5e3b..46fafc38f9 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -118,6 +118,8 @@ void vmspace_ref (struct vmspace *); void vmspace_rel (struct vmspace *); void vmspace_relexit (struct vmspace *); void vmspace_exitfree (struct proc *); +void *kmem_alloc_swapbacked(kmem_anon_desc_t *kp, vm_size_t size); +void kmem_free_swapbacked(kmem_anon_desc_t *kp); struct vmspace *vmspace_fork (struct vmspace *); void vmspace_exec (struct proc *, struct vmspace *); diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 94a8dbbbe4..311463d41f 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -88,9 +88,62 @@ struct vm_map kernel_map; struct vm_map clean_map; struct vm_map buffer_map; +/* + * Allocate pageable swap-backed anonymous memory + */ +void * +kmem_alloc_swapbacked(kmem_anon_desc_t *kp, vm_size_t size) +{ + int error; + vm_pindex_t npages; + + size = round_page(size); + npages = size / PAGE_SIZE; + + if (kp->map == NULL) + kp->map = &kernel_map; + kp->data = vm_map_min(&kernel_map); + kp->size = size; + kp->object = vm_object_allocate(OBJT_DEFAULT, npages); + + error = vm_map_find(kp->map, kp->object, NULL, 0, + &kp->data, size, + PAGE_SIZE, + 1, VM_MAPTYPE_NORMAL, + VM_PROT_ALL, VM_PROT_ALL, 0); + if (error) { + kprintf("kmem_alloc_swapbacked: %zd bytes failed %d\n", + size, error); + kp->data = (vm_offset_t)0; + kmem_free_swapbacked(kp); + return NULL; + } + return ((void *)(intptr_t)kp->data); +} + +void +kmem_free_swapbacked(kmem_anon_desc_t *kp) +{ + if (kp->data) { + /* + * The object will be deallocated by kmem_free(). + */ + kmem_free(kp->map, kp->data, kp->size); + kp->data = (vm_offset_t)0; + } else { + /* + * Failure during allocation, object must be deallocated + * manually. + */ + vm_object_deallocate(kp->object); + } + kp->object = NULL; +} + /* * Allocate pageable memory to the kernel's address map. "map" must - * be kernel_map or a submap of kernel_map. + * be kernel_map or a submap of kernel_map. Caller must adjust map or + * enter VM pages itself. * * No requirements. */ diff --git a/sys/vm/vm_kern.h b/sys/vm/vm_kern.h index a8f09aa3d3..12628bf24d 100644 --- a/sys/vm/vm_kern.h +++ b/sys/vm/vm_kern.h @@ -75,6 +75,20 @@ #include #endif +struct vm_object; + +/* + * Anonymous swap-backed kernel memory descriptor + */ +struct kmem_anon_desc { + vm_map_t map; + vm_size_t size; + vm_offset_t data; + struct vm_object *object; +}; + +typedef struct kmem_anon_desc kmem_anon_desc_t; + /* * kmem_alloc3() flags */ -- 2.41.0 From 3148f6779fc754711b51c40131a915c9deb16741 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 26 Jan 2015 15:48:03 -0800 Subject: [PATCH 11/16] hammer2 - Stabilize new I/O infrastructure and work on bulkfree * Stabilize the new asynchronous hammer_io infrastructure. * Document the new simpler bulkfree scan algorithm. The new algorithm scans meta-data in two passes, rebuilding the freemap in kernel memory. It then compares the map against the live media. The first pass transitions the freemap from (11 = allocated) to (10 = staged for deletion), the second pass transitions (10) either back to (11) if the block is found to not actually be freeable or to (00) if the block winds up being actually freeable. The two pass mechanism deals with any races and allows the scan to occur essentially unlocked, * Start work on the bulkfree scan algorithm. --- sys/vfs/hammer2/FREEMAP | 182 +++++++------- sys/vfs/hammer2/Makefile | 2 +- sys/vfs/hammer2/hammer2.h | 19 +- sys/vfs/hammer2/hammer2_bulkscan.c | 380 +++++++++++++++++++++++++++++ sys/vfs/hammer2/hammer2_chain.c | 10 + sys/vfs/hammer2/hammer2_disk.h | 74 +++++- sys/vfs/hammer2/hammer2_freemap.c | 45 +--- sys/vfs/hammer2/hammer2_io.c | 130 ++++++---- sys/vfs/hammer2/hammer2_ioctl.c | 20 +- sys/vfs/hammer2/hammer2_ioctl.h | 18 +- sys/vfs/hammer2/hammer2_vnops.c | 58 +++-- 11 files changed, 751 insertions(+), 187 deletions(-) create mode 100644 sys/vfs/hammer2/hammer2_bulkscan.c diff --git a/sys/vfs/hammer2/FREEMAP b/sys/vfs/hammer2/FREEMAP index 80be8c2168..e29dab5526 100644 --- a/sys/vfs/hammer2/FREEMAP +++ b/sys/vfs/hammer2/FREEMAP @@ -6,8 +6,9 @@ HAMMER2 Media is broken down into 2 GByte zones. Each 2 GByte zone contains a 4 MByte header (64 x 64K blocks = 0.2% of storage). The blocks in this header are reserved for various purposes. For example, - block #0 is reserved for a volume headers. Most of the remaining - 64KB blocks in this header are reserved for use by the freemap. + block #0 is reserved for a volume header in the first four zones. Most + of the remaining 64KB blocks in this header are reserved for use by the + freemap. The freemap only uses blocks from these reserved areas. In order to ensure that any of the four volume headers can be used by the mount code @@ -27,19 +28,19 @@ you have to stick with it. - One copy for live operations. This allows HAMMER2 to retire the - related buffer (or for the OS to retire the buffer cache buffer) - prior to the next flush and also allows the buffers to be flushed - asynchronously. + related buffer asynchronously in the background (or for the OS to + retire the buffer cache buffer on its own) prior to the formal + flush. The later formal flush then has less work to do. - The two remaining copies add robustness to the specification. For - example, with appropriate feature code the filesystem can tolerate - a limited number of bad blocks in the reserved area. + example, with appropriate feature code added the filesystem can + tolerate a limited number of bad blocks in the reserved area. For the moment we use a simple calculation for the freemap block. In a later version I would like to mix the blocks up a bit so the blocks in each set of 8 are not situated near each other. - RW Mount Restrictions + RW Mount Restrictions If an older volume header is explicitly selected by the mount code, any newer (presumably corrupt since the mount code didn't select it) volume @@ -106,12 +107,13 @@ The freemap does not have to be flushed by fsync/sync, but should probably be flushed at least once a minute by the normal filesystem sync. The - reason it does not have to be flushed every time is that freemap recovery + reason it does not have to be flushed with fsync is that freemap recovery is executed on-mount and will use the last fully flushed freemap TID stored in the volume header to do an incremental meta-data scan of the H2 filesystem between that TID and the last flushed TID. All blocks not found to have been marked allocated will be marked allocated. Simple as - that. + that. Since the scan is incremental, this typically costs very little + time. Freemap Granularity @@ -189,12 +191,11 @@ Initial Conditions - The freemap is a multi-indirect block structure but there is no real - reason to pre-format it in newfs_hammer2. Instead, newfs_hammer2 simply - leaves the associated top-level indirect blocks empty and uses the - (voldata->allocator_beg) field to allocate space linearly, then leaves - it to the live filesystem to initialize the freemap as more space gets - allocated. + newfs_hammer2 does not need to format the freemap. Instead, newfs_hammer2 + simply leaves the associated top-level indirect blocks empty and uses + the (voldata->allocator_beg) field to allocate space linearly, then + leaves it to the live filesystem to initialize the freemap as more space + gets allocated. The freemap does NOT use a fixed 5-level radix tree. It uses the same blockmap algorithm used for file blocks but restricts any recursion to @@ -208,71 +209,80 @@ contains a linear allocation offset that can keep track of sub-16KB allocations with certain restrictions. More random sub-16KB allocations are tracked in-memory, but will be lost (assumed to be a full 16KB) if - a crash occurs. + a crash occurs. Each 16KB chunk is denoted by a 2-bit pattern 00, 01, 10, + or 11. NOTE! All operations on the freemap occur on the current live version of the freemap, including bulkfree operations. Blocks are allocated by transitioning the 2-bit pattern in the leaf - to 11. That is, (00, 01, 10) -> (11). This handles races between the - live allocator and the asynchronous bulkfree code. A live allocation - which occurs while the asynchronous bulkfree process is running will - operate race-free by transitioning the (01) an (10) states back - to (11), which prevents bulkfree from later marking those blocks - FREE (00). - - Blocks can be freed several ways, but all block freeing operations - require at least two passes before the related blocks can actually be - reused. - - Method #1 - Removal in the filesystem marks the related freemap bitmap - POSSIBLY FREE (either 01 or 10). The asynchronous bulkfree - process later determines that the block is actually free and - transitions it to FREE (00), or moves it back to - ALLOCATED (11). - - This works whether the blocks can actually be freed or not, - so we don't care if the related blocks are part of some other - snapshot or not. bulkfree will figure it out. - - Method #2 - Removal in the filesystem ignores the freemap. The freemap - blocks are left alone (typically ALLOCATED (11)). - - In this situation bulkfree must make extra passes to determine - if blocks are possibly free, then transition the leaf bitmap - entries to POSSIBLY FREE (01 or 10). bulkfree cannot directly - transition the entries to FREE (00) without another pass. - - However, this method has numerous advantages including making - snapshot manipulation (including deletions) instantanious - and allow whole subtrees and/or large-files to be rm -rf'd - with only a single disk write to update the inode in the - best case. - - Method #3 - Brute force. *ALL* freemap bitmap entries are marked - POSSIBLY FREE and bulkfree then must do multiple passes - (particularly in order to ensure that its memory use remains - bounded) to again transition all the freemap bitmap entries - to either FREE (00) or ALLOCATED (11). - - This method can be faster than #2 but wastes a considerable - amount of write-bandwidth (and SSD wear if the target drive - is a SSD). - - In all cases the bulkfree code must make a final pass on the filesystem - to do the final transition of POSSIBLY FREE blocks to FREE (00) or - ALLOCATED (11). Again, races for the FREE (00) are handled by observing - if the bitmap code was moved to ALLOCATED (11) by the live system while - bulkfree ran asynchrnously and not transitioning the element to FREE (00) - in that situation. - - All bulkfree passes are done on meta-data. Actual data blocks do not - need to be read unless the media is being verified. H2 uses method #2 - by default and efficiency depends on how much ram the system has to - cache scan information. That said, the bulkfree process is not only - incremental but it is also interruptable and restartable. It does not - interfere with live operations other than using disk bandwidth, so - there are several ways to run it including in the background. + to 11. That is, (00, 01, 10) -> (11). + + The primary mechanism used to free a block is via the asynchronous + bulkfree scan. This scans all filesystem meta-data in two major passes + (and potentially multiple sub-passes). + + Pass#1 - The first pass figures which blocks might be freeable. The + most recently flushed meta-data topology (including all four + volume headers and all snapshots) is scanned and an in-memory + copy of the FreeMap is built from scratch. Multiple sub-scans + might be required to break the larger scan up into more easily + digested pieces based on the amount of memory available to hold + the temporary freemap. + + Any allocated blocks in the live freemap are then transitioned + from (11) to either (10) or (01) if after the scan they are + found to not be allocated. + + The blocks are still assumed to be allocated at this time and + any new allocations will transition them back to (11). + + Pass#2 - The second pass is required to deal with races against the + live filesystem while the freemap scan was running. It also + allows the freemap scans to run asynchronously from any flush, + improving concurrency. However, at least one synchronous flush + is required between Pass#1 and Pass#2. + + The second pass is a duplicate of the first pass. The meta-data + topology is scanned and a freemap is built in-memory and then + compared against the live freemap. Instead transitioning from + (11)->(10)/(01) this pass transitions from (10)/(01) to (00). + + If a block that it thinks is free is (11), no transition occurs + because this could be due to a race against the live filesystem. + + This pass will incidentally transition (10)/(01) back to (11) + if the block was found not to be allocated, but it is perfectly + acceptable for the block to remain in a (10)/(01) state after + completion. + + NOTE! The meta-data scanning passes must also explicitly scan blocks + associated with any open files, since these might represent + open-but-deleted files. These blocks must not be accidently freed + while the system is still using the file. Again, since this is + done in two passes it does not have to be synchronized against + frontend operations. So in total: + + * Topology under all four volume headers. This includes all + PFSs and snapshots. + + * Topology under all open hammer2 files. + + The Bulk-free operation is expensive but uses a bounded amount of ram. + The ADVANTAGE of this mechanism is that deletions in the live filesystem + do not have to clean up the freemap and thus do not have to recurse + the topology during the deletion. In fact, a 'rm -rf' equivalent of a + directory topology can be handled simply by blowing away the top-level + directory inode. This is instantanious and thus can be dangerous but + you always have your snapshots to fall-back on. + + The DISADVANTAGE is that all meta-data must be scanned. Twice. This + can be mitigated by using swapcache(8) to cache the meta-data on a SSD. + This is also mitigated by the fact that you can do the bulkfree scan less + often on very large filesystems which presumably have a lot of freespace + (so the interval is not as big an issue). In a sense the operation does + scale in that it takes longer on larger filesystems but also can be run + less often. The biggest issue is that *NO* space can be freed up by the live filesystem without the bulkfree process unless we optimize the case @@ -326,9 +336,17 @@ deletions in order to allow a system operator to recover from a filesystem full condition. - Despite this, situations may come up, due to having snapshots, where - deletions eat up available blocks but fail to create freeable space. - When this situation occurs the system operator may be forced to issue - emergency in-place deletions which replace existing blocks rather then - allocate new blocks. For the moment the spec for dealing with these - situations remains incomplete. + However, due to the snapshot capability as well as the possibility of + fragmentation, it is possible for the administrator to not delete enough + to actually be able to free up blocks. Once the reserve is used up + the filesystem can become unwritable. + + When this situation occurs the only way to recover is to update blocks + in-place. Updating blocks in-place will destroy the data on any + related snapshots or otherwise corrupt the snapshots. Emergency recovery + thus recommends that all related snapshots be destroyed. You can choose + not to do this in which case your snapshots might wind up containing + broken links and generate CRC failure messages. + + For the moment the spec for dealing with these situations remains + incomplete. diff --git a/sys/vfs/hammer2/Makefile b/sys/vfs/hammer2/Makefile index 402664aef3..ac33bb1bc2 100644 --- a/sys/vfs/hammer2/Makefile +++ b/sys/vfs/hammer2/Makefile @@ -7,7 +7,7 @@ CFLAGS+= -DINVARIANTS -DSMP KMOD= hammer2 SRCS= hammer2_vfsops.c hammer2_vnops.c hammer2_inode.c hammer2_ccms.c SRCS+= hammer2_chain.c hammer2_flush.c hammer2_freemap.c hammer2_cluster.c -SRCS+= hammer2_ioctl.c hammer2_msgops.c hammer2_subr.c +SRCS+= hammer2_ioctl.c hammer2_msgops.c hammer2_subr.c hammer2_bulkscan.c SRCS+= hammer2_lz4.c hammer2_io.c SRCS+= hammer2_zlib_adler32.c hammer2_zlib_deflate.c SRCS+= hammer2_zlib_inffast.c hammer2_zlib_inflate.c diff --git a/sys/vfs/hammer2/hammer2.h b/sys/vfs/hammer2/hammer2.h index 7f2051c441..183004d4cf 100644 --- a/sys/vfs/hammer2/hammer2.h +++ b/sys/vfs/hammer2/hammer2.h @@ -223,7 +223,7 @@ typedef struct hammer2_iocb hammer2_iocb_t; #define HAMMER2_IOCB_ONQ 0x00000002 #define HAMMER2_IOCB_DONE 0x00000004 #define HAMMER2_IOCB_INPROG 0x00000008 -#define HAMMER2_IOCB_DIDBP 0x00000010 /* loaded dio->buf */ +#define HAMMER2_IOCB_UNUSED10 0x00000010 #define HAMMER2_IOCB_QUICK 0x00010000 #define HAMMER2_IOCB_ZERO 0x00020000 #define HAMMER2_IOCB_READ 0x00040000 @@ -250,7 +250,7 @@ struct hammer2_io { typedef struct hammer2_io hammer2_io_t; #define HAMMER2_DIO_INPROG 0x80000000 /* bio in progress */ -#define HAMMER2_DIO_GOOD 0x40000000 /* buf data is good */ +#define HAMMER2_DIO_GOOD 0x40000000 /* dio->bp is stable */ #define HAMMER2_DIO_WAITING 0x20000000 /* (old) */ #define HAMMER2_DIO_DIRTY 0x10000000 /* flush on last drop */ @@ -558,7 +558,7 @@ typedef struct hammer2_trans hammer2_trans_t; #define HAMMER2_TRANS_CONCURRENT 0x0002 /* concurrent w/flush */ #define HAMMER2_TRANS_BUFCACHE 0x0004 /* from bioq strategy write */ #define HAMMER2_TRANS_NEWINODE 0x0008 /* caller allocating inode */ -#define HAMMER2_TRANS_FREEBATCH 0x0010 /* batch freeing code */ +#define HAMMER2_TRANS_UNUSED0010 0x0010 #define HAMMER2_TRANS_PREFLUSH 0x0020 /* preflush state */ #define HAMMER2_FREEMAP_HEUR_NRADIX 4 /* pwr 2 PBUFRADIX-MINIORADIX */ @@ -668,6 +668,14 @@ typedef struct hammer2_pfsmount hammer2_pfsmount_t; #define HAMMER2_LWINPROG_WAITING 0x80000000 #define HAMMER2_LWINPROG_MASK 0x7FFFFFFF +/* + * Bulkscan + */ +#define HAMMER2_BULK_ABORT 0x00000001 + +/* + * Misc + */ #if defined(_KERNEL) MALLOC_DECLARE(M_HAMMER2); @@ -1061,6 +1069,11 @@ int hammer2_cluster_snapshot(hammer2_trans_t *trans, hammer2_cluster_t *ocluster, hammer2_ioc_pfs_t *pfs); hammer2_cluster_t *hammer2_cluster_parent(hammer2_cluster_t *cluster); +int hammer2_bulk_scan(hammer2_trans_t *trans, hammer2_chain_t *parent, + int (*func)(hammer2_chain_t *chain, void *info), + void *info); +int hammer2_bulkfree_pass(hammer2_mount_t *hmp, + struct hammer2_ioc_bulkfree *bfi); #endif /* !_KERNEL */ #endif /* !_VFS_HAMMER2_HAMMER2_H_ */ diff --git a/sys/vfs/hammer2/hammer2_bulkscan.c b/sys/vfs/hammer2/hammer2_bulkscan.c new file mode 100644 index 0000000000..0ce38a57e4 --- /dev/null +++ b/sys/vfs/hammer2/hammer2_bulkscan.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2013-2015 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hammer2.h" + +/* + * breadth-first search + */ +typedef struct hammer2_chain_save { + TAILQ_ENTRY(hammer2_chain_save) entry; + hammer2_chain_t *parent; +} hammer2_chain_save_t; + +TAILQ_HEAD(hammer2_chain_save_list, hammer2_chain_save); +typedef struct hammer2_chain_save_list hammer2_chain_save_list_t; + +/* + * General bulk scan function with callback. Called with a referenced + * but UNLOCKED parent. The original parent is returned in the same state. + */ +int +hammer2_bulk_scan(hammer2_trans_t *trans, hammer2_chain_t *parent, + int (*func)(hammer2_chain_t *chain, void *info), + void *info) +{ + hammer2_chain_save_list_t list; + hammer2_chain_save_t *save; + int doabort = 0; + + TAILQ_INIT(&list); + hammer2_chain_ref(parent); + save = kmalloc(sizeof(*save), M_HAMMER2, M_WAITOK | M_ZERO); + save->parent = parent; + TAILQ_INSERT_TAIL(&list, save, entry); + + while ((save = TAILQ_FIRST(&list)) != NULL) { + hammer2_chain_t *chain; + int cache_index; + + TAILQ_REMOVE(&list, save, entry); + + parent = save->parent; + save->parent = NULL; + chain = NULL; + cache_index = -1; + + /* + * lock the parent, the lock eats the ref. + */ + hammer2_chain_lock(parent, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED | + HAMMER2_RESOLVE_NOREF); + + /* + * Generally loop on the contents if we have not been flagged + * for abort. + */ + while ((doabort & HAMMER2_BULK_ABORT) == 0) { + chain = hammer2_chain_scan(parent, chain, &cache_index, + HAMMER2_LOOKUP_NODATA | + HAMMER2_LOOKUP_SHARED); + if (chain == NULL) + break; + doabort |= func(chain, info); + + if (doabort & HAMMER2_BULK_ABORT) { + hammer2_chain_unlock(chain); + chain = NULL; + break; + } + switch(chain->bref.type) { + case HAMMER2_BREF_TYPE_INODE: + case HAMMER2_BREF_TYPE_FREEMAP_NODE: + case HAMMER2_BREF_TYPE_INDIRECT: + case HAMMER2_BREF_TYPE_VOLUME: + case HAMMER2_BREF_TYPE_FREEMAP: + /* + * Breadth-first scan. Chain is referenced + * to save for later and will be unlocked on + * our loop (so it isn't left locked while on + * the list). + */ + if (save == NULL) { + save = kmalloc(sizeof(*save), + M_HAMMER2, + M_WAITOK | M_ZERO); + } + hammer2_chain_ref(chain); + save->parent = chain; + TAILQ_INSERT_TAIL(&list, save, entry); + save = NULL; + break; + default: + /* does not recurse */ + break; + } + } + + /* + * Releases the lock and the ref the lock inherited. Free + * save structure if we didn't recycle it above. + */ + hammer2_chain_unlock(parent); + if (save) + kfree(save, M_HAMMER2); + } + return doabort; +} + +/* + * Bulkfree algorithm - + * + * DoTwice { + * flush sync + * Scan the whole topology and build the freemap + * ** -> 11 during scan for all elements scanned (and thus not free) + * 11 -> 10 after scan if allocated in-topo and free in-memory, mark 10 + * 10 -> 00 after scan if possibly-free in-topo and free in-memory mark 00 + * } + * + * Adjustment of the freemap ->10 and ->00 cannot occur until the topology + * scan is complete. The scan runs concurrentlyt with normal filesystem + * operations and any allocation will also remark the freemap bitmap 11. + * We handle races by performing two scans and only changing the map to + * fully free (00) if both passes believe it is free. + * + * Temporary memory in multiples of 64KB is required to reconstruct leaf + * hammer2_bmap_data blocks so they can later be compared against the live + * freemap. Each 64KB block represents 128 x 16KB x 1024 = ~2 GB of storage. + * A 32MB save area thus represents around ~1 TB. The temporary memory + * allocated can be specified. If it is not sufficient multiple topology + * passes will be made. + */ + +/* + * Bulkfree callback info + */ +typedef struct hammer2_bulkfree_info { + kmem_anon_desc_t kp; + hammer2_off_t sbase; /* sub-loop iteration */ + hammer2_off_t sstop; + hammer2_bmap_data_t *bmap; +} hammer2_bulkfree_info_t; + +static int h2_bulkfree_callback(hammer2_chain_t *chain, void *info); +static void h2_bulkfree_sync(hammer2_bulkfree_info_t *cbinfo); + +int +hammer2_bulkfree_pass(hammer2_mount_t *hmp, hammer2_ioc_bulkfree_t *bfi) +{ + hammer2_trans_t trans; + hammer2_bulkfree_info_t cbinfo; + size_t size; + int doabort = 0; + + bzero(&cbinfo, sizeof(cbinfo)); + size = (bfi->size + HAMMER2_FREEMAP_LEVELN_PSIZE - 1) & + ~(size_t)(HAMMER2_FREEMAP_LEVELN_PSIZE - 1); + cbinfo.bmap = kmem_alloc_swapbacked(&cbinfo.kp, size); + cbinfo.sbase = 0; + cbinfo.sstop = cbinfo.sbase + + size / HAMMER2_FREEMAP_LEVELN_PSIZE * /* per 64KB */ + HAMMER2_FREEMAP_LEVEL1_SIZE; /* 2GB */ + /* XXX also limit to volume size */ + + hammer2_trans_init(&trans, hmp->spmp, 0); + doabort |= hammer2_bulk_scan(&trans, &hmp->vchain, + h2_bulkfree_callback, &cbinfo); + h2_bulkfree_sync(&cbinfo); + hammer2_trans_done(&trans); + + kmem_free_swapbacked(&cbinfo.kp); + + return doabort; +} + +static int +h2_bulkfree_callback(hammer2_chain_t *chain, void *info) +{ + hammer2_bulkfree_info_t *cbinfo = info; + hammer2_bmap_data_t *bmap; + hammer2_off_t data_off; + uint16_t class; + size_t bytes; + int radix; + int error; + + error = 0; + +#if 0 + kprintf("scan chain %016jx %016jx/%-2d type=%02x\n", + (intmax_t)chain->bref.data_off, + (intmax_t)chain->bref.key, + chain->bref.keybits, + chain->bref.type); +#endif + + /* + * Calculate the data offset and determine if it is within + * the current freemap range being gathered. + */ + data_off = chain->bref.data_off & ~HAMMER2_OFF_MASK_RADIX; + if (data_off < cbinfo->sbase || data_off > cbinfo->sstop) + return 0; + if (data_off < chain->hmp->voldata.allocator_beg) + return 0; + if (data_off > chain->hmp->voldata.volu_size) + return 0; + + /* + * Calculate the information needed to generate the in-memory + * freemap record. + * + * Hammer2 does not allow allocations to cross the L1 (2GB) boundary, + * it's a problem if it does. (Or L0 (2MB) for that matter). + */ + radix = (int)(chain->bref.data_off & HAMMER2_OFF_MASK_RADIX); + bytes = (size_t)1 << radix; + class = (chain->bref.type << 8) | hammer2_devblkradix(radix); + + if (data_off + bytes > cbinfo->sstop) { + kprintf("hammer2_bulkfree_scan: illegal 2GB boundary " + "%016jx %016jx/%d\n", + (intmax_t)chain->bref.data_off, + (intmax_t)chain->bref.key, + chain->bref.keybits); + bytes = cbinfo->sstop - data_off; /* XXX */ + } + + /* + * Convert to a storage offset relative to the beginning of the + * storage range we are collecting. Then lookup the level0 bmap entry. + */ + data_off -= cbinfo->sbase; + bmap = cbinfo->bmap + (data_off >> HAMMER2_FREEMAP_LEVEL0_RADIX); + + /* + * Convert data_off to a bmap-relative value (~2MB storage range). + * Adjust linear, class, and avail. + * + * Hammer2 does not allow allocations to cross the L0 (2MB) boundary, + */ + data_off &= HAMMER2_FREEMAP_LEVEL0_MASK; + if (data_off + bytes > HAMMER2_FREEMAP_LEVEL0_SIZE) { + kprintf("hammer2_bulkfree_scan: illegal 2MB boundary " + "%016jx %016jx/%d\n", + (intmax_t)chain->bref.data_off, + (intmax_t)chain->bref.key, + chain->bref.keybits); + bytes = HAMMER2_FREEMAP_LEVEL0_SIZE - data_off; + } + + if (bmap->class == 0) { + bmap->class = class; + bmap->avail = HAMMER2_FREEMAP_LEVEL0_SIZE; + } + if (bmap->class != class) { + kprintf("hammer2_bulkfree_scan: illegal mixed class " + "%016jx %016jx/%d (%04x vs %04x)\n", + (intmax_t)chain->bref.data_off, + (intmax_t)chain->bref.key, + chain->bref.keybits, + class, bmap->class); + } + if (bmap->linear < (int32_t)data_off + (int32_t)bytes) + bmap->linear = (int32_t)data_off + (int32_t)bytes; + + /* + * Adjust the uint32_t bitmap[8]. 2 bits per entry, to code 11. + * Shortcut aligned 64KB allocations. + * + * NOTE: The allocation can be smaller than HAMMER2_FREEMAP_BLOCK_SIZE. + */ + while (bytes > 0) { + int bindex; + int bmask; + + bindex = (int)data_off >> (HAMMER2_FREEMAP_BLOCK_RADIX + + HAMMER2_BMAP_INDEX_RADIX); + bmask = 3 << ((((int)data_off & HAMMER2_BMAP_INDEX_MASK) >> + HAMMER2_FREEMAP_BLOCK_RADIX) << 1); + if ((bmap->bitmap[bindex] & bmask) == 0) { + if (bytes >= HAMMER2_FREEMAP_BLOCK_SIZE) + bmap->avail -= HAMMER2_FREEMAP_BLOCK_SIZE; + else + bmap->avail -= bytes; + bmap->bitmap[bindex] |= bmask; + } + data_off += HAMMER2_FREEMAP_BLOCK_SIZE; + if (bytes < HAMMER2_FREEMAP_BLOCK_SIZE) + bytes = 0; + else + bytes -= HAMMER2_FREEMAP_BLOCK_SIZE; + } + return error; +} + +static void +h2_bulkfree_sync(hammer2_bulkfree_info_t *cbinfo) +{ + hammer2_off_t data_off; + hammer2_bmap_data_t *bmap; + int didl1; + + kprintf("hammer2_bulkfree - range %016jx-%016jx\n", + (intmax_t)cbinfo->sbase, + (intmax_t)cbinfo->sstop); + + data_off = cbinfo->sbase; + bmap = cbinfo->bmap; + didl1 = 0; + + while (data_off < cbinfo->sstop) { + if (bmap->class) { + kprintf("%016jx %04d.%04x (avail=%7d) " + "%08x %08x %08x %08x %08x %08x %08x %08x\n", + (intmax_t)data_off, + (int)((data_off & + HAMMER2_FREEMAP_LEVEL1_MASK) >> + HAMMER2_FREEMAP_LEVEL0_RADIX), + bmap->class, + bmap->avail, + bmap->bitmap[0], bmap->bitmap[1], + bmap->bitmap[2], bmap->bitmap[3], + bmap->bitmap[4], bmap->bitmap[5], + bmap->bitmap[6], bmap->bitmap[7]); + didl1 = 1; + } + data_off += HAMMER2_FREEMAP_LEVEL0_SIZE; + ++bmap; + if ((data_off & HAMMER2_FREEMAP_LEVEL1_MASK) == 0) { + if (didl1) + kprintf("\n"); + didl1 = 0; + } + } +} diff --git a/sys/vfs/hammer2/hammer2_chain.c b/sys/vfs/hammer2/hammer2_chain.c index 3a1e097a2d..43e9d1e648 100644 --- a/sys/vfs/hammer2/hammer2_chain.c +++ b/sys/vfs/hammer2/hammer2_chain.c @@ -1222,10 +1222,14 @@ skip2: if (chain->parent) hammer2_chain_setflush(trans, chain->parent); +#if 0 /* * Adjust the freemap bitmap to indicate that the related blocks * MIGHT be freeable. Bulkfree must still determine that the blocks * are actually freeable. + * + * We no longer do this in the normal filesystem operations path + * as it interferes with the bulkfree algorithm. */ if (obref.type != HAMMER2_BREF_TYPE_FREEMAP_NODE && obref.type != HAMMER2_BREF_TYPE_FREEMAP_LEAF && @@ -1233,6 +1237,7 @@ skip2: hammer2_freemap_adjust(trans, hmp, &obref, HAMMER2_FREEMAP_DOMAYFREE); } +#endif } /* @@ -2619,11 +2624,15 @@ _hammer2_chain_delete_helper(hammer2_trans_t *trans, atomic_set_int(&chain->flags, HAMMER2_CHAIN_DELETED); } +#if 0 /* * If the deletion is permanent (i.e. the chain is not simply being * moved within the topology), adjust the freemap to indicate that * the block *might* be freeable. bulkfree must still determine * that it is actually freeable. + * + * We no longer do this in the normal filesystem operations path + * as it interferes with the bulkfree algorithm. */ if ((flags & HAMMER2_DELETE_PERMANENT) && chain->bref.type != HAMMER2_BREF_TYPE_FREEMAP_NODE && @@ -2632,6 +2641,7 @@ _hammer2_chain_delete_helper(hammer2_trans_t *trans, hammer2_freemap_adjust(trans, hmp, &chain->bref, HAMMER2_FREEMAP_DOMAYFREE); } +#endif } /* diff --git a/sys/vfs/hammer2/hammer2_disk.h b/sys/vfs/hammer2/hammer2_disk.h index e14f7295c1..c6fba0000a 100644 --- a/sys/vfs/hammer2/hammer2_disk.h +++ b/sys/vfs/hammer2/hammer2_disk.h @@ -271,11 +271,44 @@ #define HAMMER2_ZONE_FREEMAP_03 13 /* normal freemap rotation */ #define HAMMER2_ZONE_FREEMAP_04 17 /* normal freemap rotation */ #define HAMMER2_ZONE_FREEMAP_05 21 /* normal freemap rotation */ -#define HAMMER2_ZONE_FREEMAP_06 25 /* batch freeing code only */ -#define HAMMER2_ZONE_FREEMAP_07 29 /* batch freeing code only */ -#define HAMMER2_ZONE_FREEMAP_08 33 /* (non-inclusive) */ +#define HAMMER2_ZONE_FREEMAP_06 25 /* normal freemap rotation */ +#define HAMMER2_ZONE_FREEMAP_07 29 /* normal freemap rotation */ +#define HAMMER2_ZONE_FREEMAP_END 33 /* (non-inclusive) */ + +#define HAMMER2_ZONE_UNUSED33 33 +#define HAMMER2_ZONE_UNUSED34 34 +#define HAMMER2_ZONE_UNUSED35 35 +#define HAMMER2_ZONE_UNUSED36 36 +#define HAMMER2_ZONE_UNUSED37 37 +#define HAMMER2_ZONE_UNUSED38 38 +#define HAMMER2_ZONE_UNUSED39 39 +#define HAMMER2_ZONE_UNUSED40 40 +#define HAMMER2_ZONE_UNUSED41 41 +#define HAMMER2_ZONE_UNUSED42 42 +#define HAMMER2_ZONE_UNUSED43 43 +#define HAMMER2_ZONE_UNUSED44 44 +#define HAMMER2_ZONE_UNUSED45 45 +#define HAMMER2_ZONE_UNUSED46 46 +#define HAMMER2_ZONE_UNUSED47 47 +#define HAMMER2_ZONE_UNUSED48 48 +#define HAMMER2_ZONE_UNUSED49 49 +#define HAMMER2_ZONE_UNUSED50 50 +#define HAMMER2_ZONE_UNUSED51 51 +#define HAMMER2_ZONE_UNUSED52 52 +#define HAMMER2_ZONE_UNUSED53 53 +#define HAMMER2_ZONE_UNUSED54 54 +#define HAMMER2_ZONE_UNUSED55 55 +#define HAMMER2_ZONE_UNUSED56 56 +#define HAMMER2_ZONE_UNUSED57 57 +#define HAMMER2_ZONE_UNUSED58 58 +#define HAMMER2_ZONE_UNUSED59 59 +#define HAMMER2_ZONE_UNUSED60 60 +#define HAMMER2_ZONE_UNUSED61 61 #define HAMMER2_ZONE_UNUSED62 62 #define HAMMER2_ZONE_UNUSED63 63 +#define HAMMER2_ZONE_END 64 /* non-inclusive */ + +#define HAMMER2_NFREEMAPS 8 /* FREEMAP_00 - FREEMAP_07 */ /* relative to FREEMAP_x */ #define HAMMER2_ZONEFM_LEVEL1 0 /* 2GB leafmap */ @@ -284,14 +317,12 @@ #define HAMMER2_ZONEFM_LEVEL4 3 /* 2EB indmap */ /* LEVEL5 is a set of 8 blockrefs in the volume header 16EB */ - /* - * Freemap radii. Please note that LEVEL 1 blockref array entries - * point to 256-byte sections of the bitmap representing 2MB of storage. - * Even though the chain structures represent only 256 bytes, they are - * mapped using larger 16K or 64K buffer cache buffers. + * Freemap radii. Note that the LEVEL 1 blockref points to a 64KB freemap + * block containing 1024 x LEVEL0 hammer2_bmap_data structures. LEVEL 0 + * represents one structure. */ -#define HAMMER2_FREEMAP_LEVEL5_RADIX 64 /* 16EB */ +#define HAMMER2_FREEMAP_LEVEL5_RADIX 64 /* 16EB (end) */ #define HAMMER2_FREEMAP_LEVEL4_RADIX 61 /* 2EB */ #define HAMMER2_FREEMAP_LEVEL3_RADIX 51 /* 2PB */ #define HAMMER2_FREEMAP_LEVEL2_RADIX 41 /* 2TB */ @@ -300,12 +331,37 @@ #define HAMMER2_FREEMAP_LEVELN_PSIZE 65536 /* physical bytes */ +#define HAMMER2_FREEMAP_LEVEL4_SIZE ((hammer2_off_t)1 << \ + HAMMER2_FREEMAP_LEVEL4_RADIX) +#define HAMMER2_FREEMAP_LEVEL3_SIZE ((hammer2_off_t)1 << \ + HAMMER2_FREEMAP_LEVEL3_RADIX) +#define HAMMER2_FREEMAP_LEVEL2_SIZE ((hammer2_off_t)1 << \ + HAMMER2_FREEMAP_LEVEL2_RADIX) +#define HAMMER2_FREEMAP_LEVEL1_SIZE ((hammer2_off_t)1 << \ + HAMMER2_FREEMAP_LEVEL1_RADIX) +#define HAMMER2_FREEMAP_LEVEL0_SIZE ((hammer2_off_t)1 << \ + HAMMER2_FREEMAP_LEVEL0_RADIX) + +#define HAMMER2_FREEMAP_LEVEL4_MASK (HAMMER2_FREEMAP_LEVEL4_SIZE - 1) +#define HAMMER2_FREEMAP_LEVEL3_MASK (HAMMER2_FREEMAP_LEVEL3_SIZE - 1) +#define HAMMER2_FREEMAP_LEVEL2_MASK (HAMMER2_FREEMAP_LEVEL2_SIZE - 1) +#define HAMMER2_FREEMAP_LEVEL1_MASK (HAMMER2_FREEMAP_LEVEL1_SIZE - 1) +#define HAMMER2_FREEMAP_LEVEL0_MASK (HAMMER2_FREEMAP_LEVEL0_SIZE - 1) + #define HAMMER2_FREEMAP_COUNT (int)(HAMMER2_FREEMAP_LEVELN_PSIZE / \ sizeof(hammer2_bmap_data_t)) #define HAMMER2_FREEMAP_BLOCK_RADIX 14 #define HAMMER2_FREEMAP_BLOCK_SIZE (1 << HAMMER2_FREEMAP_BLOCK_RADIX) #define HAMMER2_FREEMAP_BLOCK_MASK (HAMMER2_FREEMAP_BLOCK_SIZE - 1) +/* + * bitmap[] structure. 2 bits per HAMMER2_FREEMAP_BLOCK_SIZE. Each bitmap[] + * element is 32 bits and thus represents 16 blocks (radix 4). + */ +#define HAMMER2_BMAP_INDEX_RADIX 4 +#define HAMMER2_BMAP_INDEX_SIZE (HAMMER2_FREEMAP_BLOCK_SIZE * 16) +#define HAMMER2_BMAP_INDEX_MASK (HAMMER2_BMAP_INDEX_SIZE - 1) + /* * Two linear areas can be reserved after the initial 2MB segment in the base * zone (the one starting at offset 0). These areas are NOT managed by the diff --git a/sys/vfs/hammer2/hammer2_freemap.c b/sys/vfs/hammer2/hammer2_freemap.c index 94287a7d17..0af6144e8d 100644 --- a/sys/vfs/hammer2/hammer2_freemap.c +++ b/sys/vfs/hammer2/hammer2_freemap.c @@ -111,43 +111,20 @@ hammer2_freemap_reserve(hammer2_trans_t *trans, hammer2_chain_t *chain, * is the first allocation of the block (verses a modification of an * existing block), we use index 0, otherwise we use the next rotating * index. - * - * NORMAL transactions use FREEMAP sections 0-5, while FREEBATCH - * transactions use sections 6 and 7. FREEBATCH transactions are - * used by the batch freeing code to spool-off in-memory structures - * used to track the batch free scan. */ - if (trans->flags & HAMMER2_TRANS_FREEBATCH) { - if ((bref->data_off & ~HAMMER2_OFF_MASK_RADIX) == 0) { - index = (HAMMER2_ZONE_FREEMAP_06 - - HAMMER2_ZONE_FREEMAP_00) / 4; - } else { - off = bref->data_off & ~HAMMER2_OFF_MASK_RADIX & - (((hammer2_off_t)1 << - HAMMER2_FREEMAP_LEVEL1_RADIX) - 1); - off = off / HAMMER2_PBUFSIZE; - KKASSERT(off >= HAMMER2_ZONE_FREEMAP_06 && - off < HAMMER2_ZONE_FREEMAP_08); - index = (int)(off - HAMMER2_ZONE_FREEMAP_00) / 4; - KKASSERT(index >= 6 && index < 8); - if (++index == 8) - index = 6; - } + if ((bref->data_off & ~HAMMER2_OFF_MASK_RADIX) == 0) { + index = 0; } else { - if ((bref->data_off & ~HAMMER2_OFF_MASK_RADIX) == 0) { + off = bref->data_off & ~HAMMER2_OFF_MASK_RADIX & + (((hammer2_off_t)1 << + HAMMER2_FREEMAP_LEVEL1_RADIX) - 1); + off = off / HAMMER2_PBUFSIZE; + KKASSERT(off >= HAMMER2_ZONE_FREEMAP_00 && + off < HAMMER2_ZONE_FREEMAP_END); + index = (int)(off - HAMMER2_ZONE_FREEMAP_00) / 4; + KKASSERT(index >= 0 && index < HAMMER2_NFREEMAPS); + if (++index == HAMMER2_NFREEMAPS) index = 0; - } else { - off = bref->data_off & ~HAMMER2_OFF_MASK_RADIX & - (((hammer2_off_t)1 << - HAMMER2_FREEMAP_LEVEL1_RADIX) - 1); - off = off / HAMMER2_PBUFSIZE; - KKASSERT(off >= HAMMER2_ZONE_FREEMAP_00 && - off < HAMMER2_ZONE_FREEMAP_06); - index = (int)(off - HAMMER2_ZONE_FREEMAP_00) / 4; - KKASSERT(index >= 0 && index < 6); - if (++index == 6) - index = 0; - } } /* diff --git a/sys/vfs/hammer2/hammer2_io.c b/sys/vfs/hammer2/hammer2_io.c index 2fe5be1b2a..308e28703c 100644 --- a/sys/vfs/hammer2/hammer2_io.c +++ b/sys/vfs/hammer2/hammer2_io.c @@ -62,13 +62,6 @@ struct hammer2_cleanupcb_info { int count; }; -#define HAMMER2_DIO_INPROG 0x80000000 -#define HAMMER2_DIO_GOOD 0x40000000 /* buf/bio is good */ -#define HAMMER2_DIO_WAITING 0x20000000 /* iocb's queued */ -#define HAMMER2_DIO_DIRTY 0x10000000 /* flush on last drop */ - -#define HAMMER2_DIO_MASK 0x0FFFFFFF - #define HAMMER2_GETBLK_GOOD 0 #define HAMMER2_GETBLK_QUEUED 1 #define HAMMER2_GETBLK_OWNED 2 @@ -95,7 +88,7 @@ hammer2_io_getblk(hammer2_mount_t *hmp, off_t lbase, int lsize, KKASSERT(pbase != 0 && ((lbase + lsize - 1) & pmask) == pbase); /* - * Access/Allocate the DIO + * Access/Allocate the DIO, bump dio->refs to prevent destruction. */ spin_lock_shared(&hmp->io_spin); dio = RB_LOOKUP(hammer2_io_tree, &hmp->iotree, pbase); @@ -149,9 +142,14 @@ hammer2_io_getblk(hammer2_mount_t *hmp, off_t lbase, int lsize, } /* - * Try to own the buffer. If we cannot we queue the iocb. + * Try to own the DIO by setting INPROG so we can issue + * I/O on it. */ if (refs & HAMMER2_DIO_INPROG) { + /* + * If DIO_INPROG is already set then set WAITING and + * queue the iocb. + */ spin_lock(&dio->spin); if (atomic_cmpset_int(&dio->refs, refs, refs | HAMMER2_DIO_WAITING)) { @@ -164,6 +162,10 @@ hammer2_io_getblk(hammer2_mount_t *hmp, off_t lbase, int lsize, spin_unlock(&dio->spin); /* retry */ } else { + /* + * If DIO_INPROG is not set then set it and issue the + * callback immediately to start I/O. + */ if (atomic_cmpset_int(&dio->refs, refs, refs | HAMMER2_DIO_INPROG)) { iocb->flags |= HAMMER2_IOCB_INPROG; @@ -179,7 +181,7 @@ hammer2_io_getblk(hammer2_mount_t *hmp, off_t lbase, int lsize, } /* - * The iocb is done. + * The originator of the iocb is finished with it. */ void hammer2_io_complete(hammer2_iocb_t *iocb) @@ -191,9 +193,10 @@ hammer2_io_complete(hammer2_iocb_t *iocb) uint32_t nflags; /* - * If IOCB_INPROG is not set then the completion was synchronous. - * We can set IOCB_DONE safely without having to worry about waiters. - * XXX + * If IOCB_INPROG was not set completion is synchronous due to the + * buffer already being good. We can simply set IOCB_DONE and return. + * In this situation DIO_INPROG is not set and we have no visibility + * on dio->bp. */ if ((iocb->flags & HAMMER2_IOCB_INPROG) == 0) { iocb->flags |= HAMMER2_IOCB_DONE; @@ -201,26 +204,28 @@ hammer2_io_complete(hammer2_iocb_t *iocb) } /* - * bp is held for all comers, make sure the lock is not owned by - * a particular thread. + * The iocb was queued, obtained DIO_INPROG, and its callback was + * made. The callback is now complete. We still own DIO_INPROG. + * + * We can set DIO_GOOD if no error occurred, which gives certain + * stability guarantees to dio->bp and allows other accessors to + * short-cut access. DIO_GOOD cannot be cleared until the last + * ref is dropped. */ - if (iocb->flags & HAMMER2_IOCB_DIDBP) + KKASSERT(dio->refs & HAMMER2_DIO_INPROG); + if (dio->bp) { BUF_KERNPROC(dio->bp); - - /* - * Set the GOOD bit on completion with no error if dio->bp is - * not NULL. Only applicable if INPROG was set. - */ - if (dio->bp && iocb->error == 0) - atomic_set_int(&dio->refs, HAMMER2_DIO_GOOD); + if ((dio->bp->b_flags & B_ERROR) == 0) { + KKASSERT(dio->bp->b_flags & B_CACHE); + atomic_set_int(&dio->refs, HAMMER2_DIO_GOOD); + } + } for (;;) { oflags = iocb->flags; cpu_ccfence(); nflags = oflags; - nflags &= ~(HAMMER2_IOCB_DIDBP | - HAMMER2_IOCB_WAKEUP | - HAMMER2_IOCB_INPROG); + nflags &= ~(HAMMER2_IOCB_WAKEUP | HAMMER2_IOCB_INPROG); nflags |= HAMMER2_IOCB_DONE; if (atomic_cmpset_int(&iocb->flags, oflags, nflags)) { @@ -229,12 +234,14 @@ hammer2_io_complete(hammer2_iocb_t *iocb) /* SMP: iocb is now stale */ break; } + /* retry */ } iocb = NULL; /* - * Now finish up the dio. If another iocb is pending chain to it, - * otherwise clear INPROG (and WAITING). + * Now finish up the dio. If another iocb is pending chain to it + * leaving DIO_INPROG set. Otherwise clear DIO_INPROG + * (and DIO_WAITING). */ for (;;) { orefs = dio->refs; @@ -260,7 +267,7 @@ hammer2_io_complete(hammer2_iocb_t *iocb) } /* - * + * Wait for an iocb's I/O to finish. */ void hammer2_iocb_wait(hammer2_iocb_t *iocb) @@ -283,8 +290,10 @@ hammer2_iocb_wait(hammer2_iocb_t *iocb) } /* - * Release our ref on *diop, dispose of the underlying buffer, and flush - * on last drop if it was dirty. + * Release our ref on *diop. + * + * On the last ref we must atomically clear DIO_GOOD and set DIO_INPROG, + * then dispose of the underlying buffer. */ void hammer2_io_putblk(hammer2_io_t **diop) @@ -400,6 +409,9 @@ hammer2_io_putblk(hammer2_io_t **diop) /* * Cleanup any dio's with (INPROG | refs) == 0. + * + * Called to clean up cached DIOs on umount after all activity has been + * flushed. */ static int @@ -465,17 +477,19 @@ hammer2_iocb_new_callback(hammer2_iocb_t *iocb) int gbctl = (iocb->flags & HAMMER2_IOCB_QUICK) ? GETBLK_NOWAIT : 0; /* - * If INPROG is not set the dio already has a good buffer and we + * If IOCB_INPROG is not set the dio already has a good buffer and we * can't mess with it other than zero the requested range. * - * If INPROG is set it gets a bit messy. + * If IOCB_INPROG is set we also own DIO_INPROG at this time and can + * do what needs to be done with dio->bp. */ if (iocb->flags & HAMMER2_IOCB_INPROG) { if ((iocb->flags & HAMMER2_IOCB_READ) == 0) { if (iocb->lsize == dio->psize) { /* * Fully covered buffer, try to optimize to - * avoid any I/O. + * avoid any I/O. We might already have the + * buffer due to iocb chaining. */ if (dio->bp == NULL) { dio->bp = getblk(dio->hmp->devvp, @@ -484,21 +498,28 @@ hammer2_iocb_new_callback(hammer2_iocb_t *iocb) } if (dio->bp) { vfs_bio_clrbuf(dio->bp); - if (iocb->flags & HAMMER2_IOCB_QUICK) { - dio->bp->b_flags |= B_CACHE; - bqrelse(dio->bp); - dio->bp = NULL; - } + dio->bp->b_flags |= B_CACHE; } } else if (iocb->flags & HAMMER2_IOCB_QUICK) { /* * Partial buffer, quick mode. Do nothing. + * Do not instantiate the buffer or try to + * mark it B_CACHE because other portions of + * the buffer might have to be read by other + * accessors. */ } else if (dio->bp == NULL || (dio->bp->b_flags & B_CACHE) == 0) { /* * Partial buffer, normal mode, requires * read-before-write. Chain the read. + * + * We might already have the buffer due to + * iocb chaining. XXX unclear if we really + * need to write/release it and reacquire + * in that case. + * + * QUEUE ASYNC I/O, IOCB IS NOT YET COMPLETE. */ if (dio->bp) { if (dio->refs & HAMMER2_DIO_DIRTY) @@ -513,7 +534,7 @@ hammer2_iocb_new_callback(hammer2_iocb_t *iocb) hammer2_io_callback, iocb); return; } /* else buffer is good */ - } + } /* else callback from breadcb is complete */ } if (dio->bp) { if (iocb->flags & HAMMER2_IOCB_ZERO) @@ -576,8 +597,28 @@ hammer2_iocb_bread_callback(hammer2_iocb_t *iocb) off_t peof; int error; + /* + * If IOCB_INPROG is not set the dio already has a good buffer and we + * can't mess with it other than zero the requested range. + * + * If IOCB_INPROG is set we also own DIO_INPROG at this time and can + * do what needs to be done with dio->bp. + */ if (iocb->flags & HAMMER2_IOCB_INPROG) { - if (hammer2_cluster_enable) { + if (dio->bp && (dio->bp->b_flags & B_CACHE)) { + /* + * Already good, likely due to being chained from + * another iocb. + */ + error = 0; + } else if (hammer2_cluster_enable) { + /* + * Synchronous cluster I/O for now. + */ + if (dio->bp) { + bqrelse(dio->bp); + dio->bp = NULL; + } peof = (dio->pbase + HAMMER2_SEGMASK64) & ~HAMMER2_SEGMASK64; error = cluster_read(dio->hmp->devvp, peof, dio->pbase, @@ -585,6 +626,13 @@ hammer2_iocb_bread_callback(hammer2_iocb_t *iocb) dio->psize, HAMMER2_PBUFSIZE*4, &dio->bp); } else { + /* + * Synchronous I/O for now. + */ + if (dio->bp) { + bqrelse(dio->bp); + dio->bp = NULL; + } error = bread(dio->hmp->devvp, dio->pbase, dio->psize, &dio->bp); } diff --git a/sys/vfs/hammer2/hammer2_ioctl.c b/sys/vfs/hammer2/hammer2_ioctl.c index 06372d362b..cb39c61386 100644 --- a/sys/vfs/hammer2/hammer2_ioctl.c +++ b/sys/vfs/hammer2/hammer2_ioctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The DragonFly Project. All rights reserved. + * Copyright (c) 2011-2015 The DragonFly Project. All rights reserved. * * This code is derived from software contributed to The DragonFly Project * by Matthew Dillon @@ -61,6 +61,7 @@ static int hammer2_ioctl_debug_dump(hammer2_inode_t *ip); //static int hammer2_ioctl_inode_comp_set(hammer2_inode_t *ip, void *data); //static int hammer2_ioctl_inode_comp_rec_set(hammer2_inode_t *ip, void *data); //static int hammer2_ioctl_inode_comp_rec_set2(hammer2_inode_t *ip, void *data); +static int hammer2_ioctl_bulkfree_scan(hammer2_inode_t *ip, void *data); int hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, int fflag, @@ -133,6 +134,9 @@ hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, int fflag, if (error == 0) error = hammer2_ioctl_inode_set(ip, data); break; + case HAMMER2IOC_BULKFREE_SCAN: + error = hammer2_ioctl_bulkfree_scan(ip, data); + break; /*case HAMMER2IOC_INODE_COMP_SET: error = hammer2_ioctl_inode_comp_set(ip, data); break; @@ -693,3 +697,17 @@ hammer2_ioctl_debug_dump(hammer2_inode_t *ip) } return 0; } + +static +int +hammer2_ioctl_bulkfree_scan(hammer2_inode_t *ip, void *data) +{ + hammer2_ioc_bulkfree_t *bfi = data; + hammer2_mount_t *hmp = ip->pmp->iroot->cluster.focus->hmp; + int error; + + /* XXX run local cluster targets only */ + error = hammer2_bulkfree_pass(hmp, bfi); + + return error; +} diff --git a/sys/vfs/hammer2/hammer2_ioctl.h b/sys/vfs/hammer2/hammer2_ioctl.h index 8c67f144f4..0d0cd137d9 100644 --- a/sys/vfs/hammer2/hammer2_ioctl.h +++ b/sys/vfs/hammer2/hammer2_ioctl.h @@ -117,6 +117,22 @@ typedef struct hammer2_ioc_inode hammer2_ioc_inode_t; #define HAMMER2IOC_INODE_FLAG_DQUOTA 0x00000002 #define HAMMER2IOC_INODE_FLAG_COPIES 0x00000004 +/* + * Ioctl for bulkfree scan + */ +struct hammer2_ioc_bulkfree { + hammer2_off_t sbase; /* starting storage offset */ + hammer2_off_t sstop; /* (set on return) */ + size_t size; /* swapable kernel memory to use */ + hammer2_off_t count_allocated; /* alloc fixups this run */ + hammer2_off_t count_freed; /* bytes freed this run */ + hammer2_off_t total_fragmented; /* merged result */ + hammer2_off_t total_allocated; /* merged result */ + hammer2_off_t total_scanned; /* bytes of storage */ +}; + +typedef struct hammer2_ioc_bulkfree hammer2_ioc_bulkfree_t; + /* * Ioctl list */ @@ -144,7 +160,7 @@ typedef struct hammer2_ioc_inode hammer2_ioc_inode_t; /*#define HAMMER2IOC_INODE_COMP_SET _IOWR('h', 88, struct hammer2_ioc_inode) //set compression mode on inode #define HAMMER2IOC_INODE_COMP_REC_SET _IOWR('h', 89, struct hammer2_ioc_inode) #define HAMMER2IOC_INODE_COMP_REC_SET2 _IOWR('h', 90, struct hammer2_ioc_inode)*/ - #define HAMMER2IOC_DEBUG_DUMP _IOWR('h', 91, int) +#define HAMMER2IOC_BULKFREE_SCAN _IOWR('h', 92, struct hammer2_ioc_bulkfree) #endif /* !_VFS_HAMMER2_IOCTL_H_ */ diff --git a/sys/vfs/hammer2/hammer2_vnops.c b/sys/vfs/hammer2/hammer2_vnops.c index b74dce99df..da5023b079 100644 --- a/sys/vfs/hammer2/hammer2_vnops.c +++ b/sys/vfs/hammer2/hammer2_vnops.c @@ -2174,26 +2174,43 @@ hammer2_strategy_read_callback(hammer2_iocb_t *iocb) * is the cluster index for iteration. */ cluster = iocb->cluster; - dio = iocb->dio; /* can be NULL */ + dio = iocb->dio; /* can be NULL if iocb not in progress */ /* - * Work to do if INPROG set, else data already available. + * Work to do if INPROG set, else dio is already good or dio is + * NULL (which is the shortcut case if chain->data is already good). */ if (iocb->flags & HAMMER2_IOCB_INPROG) { /* - * read not issued yet, chain the iocb to execute the - * read operation. + * Read attempt not yet made. Issue an asynchronous read + * if necessary and return, operation will chain back to + * this function. */ if ((iocb->flags & HAMMER2_IOCB_READ) == 0) { - iocb->flags |= HAMMER2_IOCB_READ; - breadcb(dio->hmp->devvp, dio->pbase, dio->psize, - hammer2_io_callback, iocb); - return; + if (dio->bp == NULL || + (dio->bp->b_flags & B_CACHE) == 0) { + if (dio->bp) { + bqrelse(dio->bp); + dio->bp = NULL; + } + iocb->flags |= HAMMER2_IOCB_READ; + breadcb(dio->hmp->devvp, + dio->pbase, dio->psize, + hammer2_io_callback, iocb); + return; + } } + } - /* - * check results. - */ + /* + * If we have a DIO it is now done, check for an error and + * calculate the data. + * + * If there is no DIO it is an optimization by + * hammer2_cluster_load_async(), the data is available in + * chain->data. + */ + if (dio) { if (dio->bp->b_flags & B_ERROR) { i = (int)iocb->lbase + 1; if (i >= cluster->nchains) { @@ -2203,7 +2220,7 @@ hammer2_strategy_read_callback(hammer2_iocb_t *iocb) biodone(bio); hammer2_cluster_unlock(cluster); } else { - hammer2_io_complete(iocb); + hammer2_io_complete(iocb); /* XXX */ chain = cluster->array[i]; kprintf("hammer2: IO CHAIN-%d %p\n", i, chain); hammer2_adjreadcounter(&chain->bref, @@ -2222,6 +2239,9 @@ hammer2_strategy_read_callback(hammer2_iocb_t *iocb) chain = iocb->chain; data = hammer2_io_data(dio, chain->bref.data_off); } else { + /* + * Special synchronous case, data present in chain->data. + */ chain = iocb->chain; data = (void *)chain->data; } @@ -2272,9 +2292,17 @@ hammer2_strategy_read_callback(hammer2_iocb_t *iocb) hammer2_io_bqrelse(&dio); panic("hammer2_strategy_read: unknown bref type"); } - hammer2_io_complete(iocb); - hammer2_cluster_unlock(cluster); - biodone(bio); + + /* + * Once the iocb is cleaned up the DIO (if any) will no longer be + * in-progress but will still have a ref. Be sure to release + * the ref. + */ + hammer2_io_complete(iocb); /* physical management */ + if (dio) /* physical dio & buffer */ + hammer2_io_bqrelse(&dio); + hammer2_cluster_unlock(cluster); /* cluster management */ + biodone(bio); /* logical buffer */ } static -- 2.41.0 From d0fcd3ec4a1cbbfa32581cf24ecd6f3509f1f57c Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 26 Jan 2015 18:00:53 -0800 Subject: [PATCH 12/16] hammer2 - bulkfree work 2/many * Compare the in-memory bitmap against the on-media bitmap and issue transitions. in-memory 00 - 11 (allocated) -> 10 (staged) in-memory 00 - 10 (staged) -> 00 (free) in-memory 11 - 10 (staged) -> 11 (allocated) (handles live races) --- sys/vfs/hammer2/hammer2_bulkscan.c | 237 ++++++++++++++++++++++++++--- 1 file changed, 216 insertions(+), 21 deletions(-) diff --git a/sys/vfs/hammer2/hammer2_bulkscan.c b/sys/vfs/hammer2/hammer2_bulkscan.c index 0ce38a57e4..4b8afef4da 100644 --- a/sys/vfs/hammer2/hammer2_bulkscan.c +++ b/sys/vfs/hammer2/hammer2_bulkscan.c @@ -179,14 +179,23 @@ hammer2_bulk_scan(hammer2_trans_t *trans, hammer2_chain_t *parent, * Bulkfree callback info */ typedef struct hammer2_bulkfree_info { + hammer2_mount_t *hmp; + hammer2_trans_t *trans; kmem_anon_desc_t kp; hammer2_off_t sbase; /* sub-loop iteration */ hammer2_off_t sstop; hammer2_bmap_data_t *bmap; + long count_10_00; + long count_11_10; + long count_10_11; + long count_l0cleans; + long count_linadjusts; } hammer2_bulkfree_info_t; static int h2_bulkfree_callback(hammer2_chain_t *chain, void *info); static void h2_bulkfree_sync(hammer2_bulkfree_info_t *cbinfo); +static void h2_bulkfree_sync_adjust(hammer2_bulkfree_info_t *cbinfo, + hammer2_bmap_data_t *live, hammer2_bmap_data_t *bmap); int hammer2_bulkfree_pass(hammer2_mount_t *hmp, hammer2_ioc_bulkfree_t *bfi) @@ -196,9 +205,13 @@ hammer2_bulkfree_pass(hammer2_mount_t *hmp, hammer2_ioc_bulkfree_t *bfi) size_t size; int doabort = 0; + /* hammer2_vfs_sync(hmp->mp, MNT_WAIT); XXX */ + bzero(&cbinfo, sizeof(cbinfo)); size = (bfi->size + HAMMER2_FREEMAP_LEVELN_PSIZE - 1) & ~(size_t)(HAMMER2_FREEMAP_LEVELN_PSIZE - 1); + cbinfo.trans = &trans; + cbinfo.hmp = hmp; cbinfo.bmap = kmem_alloc_swapbacked(&cbinfo.kp, size); cbinfo.sbase = 0; cbinfo.sstop = cbinfo.sbase + @@ -214,6 +227,13 @@ hammer2_bulkfree_pass(hammer2_mount_t *hmp, hammer2_ioc_bulkfree_t *bfi) kmem_free_swapbacked(&cbinfo.kp); + kprintf("bulkfree pass statistics:\n"); + kprintf(" transition->free %ld\n", cbinfo.count_10_00); + kprintf(" transition->staged %ld\n", cbinfo.count_11_10); + kprintf(" raced on %ld\n", cbinfo.count_10_11); + kprintf(" ~2MB segs cleaned %ld\n", cbinfo.count_l0cleans); + kprintf(" linear adjusts %ld\n", cbinfo.count_linadjusts); + return doabort; } @@ -316,12 +336,19 @@ h2_bulkfree_callback(hammer2_chain_t *chain, void *info) */ while (bytes > 0) { int bindex; - int bmask; + uint32_t bmask; bindex = (int)data_off >> (HAMMER2_FREEMAP_BLOCK_RADIX + HAMMER2_BMAP_INDEX_RADIX); bmask = 3 << ((((int)data_off & HAMMER2_BMAP_INDEX_MASK) >> HAMMER2_FREEMAP_BLOCK_RADIX) << 1); + + /* + * NOTE: The 'avail' calculation will not be correct because + * it does not take into account distinct sub-16K + * allocations (which we can't track without eating a + * lot more memory). Use it here only as a hint. + */ if ((bmap->bitmap[bindex] & bmask) == 0) { if (bytes >= HAMMER2_FREEMAP_BLOCK_SIZE) bmap->avail -= HAMMER2_FREEMAP_BLOCK_SIZE; @@ -338,12 +365,30 @@ h2_bulkfree_callback(hammer2_chain_t *chain, void *info) return error; } +/* + * Synchronize the in-memory bitmap with the live freemap. This is not a + * direct copy. Instead the bitmaps must be compared: + * + * In-memory Live-freemap + * 00 11 -> 10 + * 10 -> 00 + * 11 10 -> 11 handles race against live + * ** -> 11 nominally warn of corruption + * + */ static void h2_bulkfree_sync(hammer2_bulkfree_info_t *cbinfo) { hammer2_off_t data_off; + hammer2_key_t key; + hammer2_key_t key_dummy; hammer2_bmap_data_t *bmap; - int didl1; + hammer2_bmap_data_t *live; + hammer2_chain_t *live_parent; + hammer2_chain_t *live_chain; + int cache_index = -1; + int bmapindex; + int ddflag; kprintf("hammer2_bulkfree - range %016jx-%016jx\n", (intmax_t)cbinfo->sbase, @@ -351,30 +396,180 @@ h2_bulkfree_sync(hammer2_bulkfree_info_t *cbinfo) data_off = cbinfo->sbase; bmap = cbinfo->bmap; - didl1 = 0; + + live_parent = &cbinfo->hmp->fchain; + hammer2_chain_lock(live_parent, HAMMER2_RESOLVE_ALWAYS); + live_chain = NULL; while (data_off < cbinfo->sstop) { - if (bmap->class) { - kprintf("%016jx %04d.%04x (avail=%7d) " - "%08x %08x %08x %08x %08x %08x %08x %08x\n", - (intmax_t)data_off, - (int)((data_off & - HAMMER2_FREEMAP_LEVEL1_MASK) >> - HAMMER2_FREEMAP_LEVEL0_RADIX), - bmap->class, - bmap->avail, - bmap->bitmap[0], bmap->bitmap[1], - bmap->bitmap[2], bmap->bitmap[3], - bmap->bitmap[4], bmap->bitmap[5], - bmap->bitmap[6], bmap->bitmap[7]); - didl1 = 1; + /* + * The freemap is not used below allocator_beg or beyond + * volu_size. + */ + if (data_off < cbinfo->hmp->voldata.allocator_beg) + goto next; + if (data_off > cbinfo->hmp->voldata.volu_size) + goto next; + + /* + * Locate the freemap leaf on the live filesystem + */ + key = (data_off & ~HAMMER2_FREEMAP_LEVEL1_MASK); + if (live_chain == NULL || live_chain->bref.key != key) { + if (live_chain) + hammer2_chain_unlock(live_chain); + live_chain = hammer2_chain_lookup( + &live_parent, + &key_dummy, + key, + key + HAMMER2_FREEMAP_LEVEL1_MASK, + &cache_index, + HAMMER2_LOOKUP_ALWAYS, + &ddflag); + if (live_chain) + kprintf("live_chain %016jx\n", (intmax_t)key); + + } + if (live_chain == NULL) { + if (bmap->class && + bmap->avail != HAMMER2_FREEMAP_LEVEL0_SIZE) { + kprintf("hammer2_bulkfree: cannot locate " + "live leaf for allocated data " + "near %016jx\n", + (intmax_t)data_off); + } + goto next; + } + + bmapindex = (data_off & HAMMER2_FREEMAP_LEVEL1_MASK) >> + HAMMER2_FREEMAP_LEVEL0_RADIX; + live = &live_chain->data->bmdata[bmapindex]; + + /* + * For now just handle the 11->10, 10->00, and 10->11 + * transitions. + */ + if (live->class == 0 || + live->avail == HAMMER2_FREEMAP_LEVEL0_SIZE) { + goto next; } + if (bcmp(live->bitmap, bmap->bitmap, sizeof(bmap->bitmap)) == 0) + goto next; + kprintf("live %016jx %04d.%04x (avail=%d)\n", + data_off, bmapindex, live->class, live->avail); + + hammer2_chain_modify(cbinfo->trans, live_chain, 0); + h2_bulkfree_sync_adjust(cbinfo, live, bmap); +next: data_off += HAMMER2_FREEMAP_LEVEL0_SIZE; ++bmap; - if ((data_off & HAMMER2_FREEMAP_LEVEL1_MASK) == 0) { - if (didl1) - kprintf("\n"); - didl1 = 0; + } + if (live_chain) + hammer2_chain_unlock(live_chain); + if (live_parent) + hammer2_chain_unlock(live_parent); +} + +static +void +h2_bulkfree_sync_adjust(hammer2_bulkfree_info_t *cbinfo, + hammer2_bmap_data_t *live, hammer2_bmap_data_t *bmap) +{ + int bindex; + int scount; + uint32_t lmask; + uint32_t mmask; + + for (bindex = 0; bindex < 8; ++bindex) { + lmask = live->bitmap[bindex]; + mmask = bmap->bitmap[bindex]; + if (lmask == mmask) + continue; + + for (scount = 0; scount < 32; scount += 2) { + if ((mmask & 3) == 0) { + /* + * in-memory 00 live 11 -> 10 + * live 10 -> 00 + */ + switch (lmask & 3) { + case 0: /* 00 */ + break; + case 1: /* 01 */ + kprintf("hammer2_bulkfree: cannot " + "transition m=00/l=01\n"); + break; + case 2: /* 10 -> 00 */ + live->bitmap[bindex] &= ~(2 << scount); + ++cbinfo->count_10_00; + break; + case 3: /* 11 -> 10 */ + live->bitmap[bindex] &= ~(1 << scount); + ++cbinfo->count_11_10; + break; + } + } else if ((lmask & 3) == 3) { + /* + * in-memory 11 live 10 -> 11 + * live ** -> 11 + */ + switch (lmask & 3) { + case 0: /* 00 */ + kprintf("hammer2_bulkfree: cannot " + "transition m=11/l=00\n"); + break; + case 1: /* 01 */ + kprintf("hammer2_bulkfree: cannot " + "transition m=11/l=01\n"); + break; + case 2: /* 10 -> 11 */ + live->bitmap[bindex] |= (1 << scount); + ++cbinfo->count_10_11; + break; + case 3: /* 11 */ + break; + } + } + mmask >>= 2; + lmask >>= 2; } } + + /* + * Determine if the live bitmap is completely free and reset its + * fields if so. Otherwise check to see if we can reduce the linear + * offset. + */ + for (bindex = 7; bindex >= 0; --bindex) { + if (live->bitmap[bindex] != 0) + break; + } + if (bindex < 0) { + live->avail = HAMMER2_FREEMAP_LEVEL0_SIZE; + live->class = 0; + live->linear = 0; + ++cbinfo->count_l0cleans; + } else if (bindex < 7) { + ++bindex; + if (live->linear > bindex * HAMMER2_FREEMAP_BLOCK_SIZE) + live->linear = bindex * HAMMER2_FREEMAP_BLOCK_SIZE; + ++cbinfo->count_linadjusts; + } + +#if 0 + if (bmap->class) { + kprintf("%016jx %04d.%04x (avail=%7d) " + "%08x %08x %08x %08x %08x %08x %08x %08x\n", + (intmax_t)data_off, + (int)((data_off & + HAMMER2_FREEMAP_LEVEL1_MASK) >> + HAMMER2_FREEMAP_LEVEL0_RADIX), + bmap->class, + bmap->avail, + bmap->bitmap[0], bmap->bitmap[1], + bmap->bitmap[2], bmap->bitmap[3], + bmap->bitmap[4], bmap->bitmap[5], + bmap->bitmap[6], bmap->bitmap[7]); + } +#endif } -- 2.41.0 From 00261fe04a7b5b22c2c2f65e5f2ded5761ac32e1 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 26 Jan 2015 18:04:30 -0800 Subject: [PATCH 13/16] hammer2 - Add bulkfree directive. * Add a bulkfree directive for testing the bulkfree code. --- sbin/hammer2/Makefile | 1 + sbin/hammer2/cmd_bulkfree.c | 57 +++++++++++++++++++++++++++++++++++++ sbin/hammer2/cmd_debug.c | 2 +- sbin/hammer2/hammer2.h | 1 + sbin/hammer2/main.c | 14 +++++++-- 5 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 sbin/hammer2/cmd_bulkfree.c diff --git a/sbin/hammer2/Makefile b/sbin/hammer2/Makefile index 616602dae8..c30d56a54e 100644 --- a/sbin/hammer2/Makefile +++ b/sbin/hammer2/Makefile @@ -3,6 +3,7 @@ SRCS= main.c subs.c icrc.c SRCS+= cmd_remote.c cmd_snapshot.c cmd_pfs.c SRCS+= cmd_service.c cmd_leaf.c cmd_debug.c SRCS+= cmd_rsa.c cmd_stat.c cmd_setcomp.c cmd_setcheck.c +SRCS+= cmd_bulkfree.c SRCS+= print_inode.c #MAN= hammer2.8 NOMAN= TRUE diff --git a/sbin/hammer2/cmd_bulkfree.c b/sbin/hammer2/cmd_bulkfree.c new file mode 100644 index 0000000000..dc273943f7 --- /dev/null +++ b/sbin/hammer2/cmd_bulkfree.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hammer2.h" + +int +cmd_bulkfree(const char *sel_path) +{ + hammer2_ioc_bulkfree_t bfi; + int ecode; + int fd; + int res; + + bzero(&bfi, sizeof(bfi)); + bfi.size = 8192 * 1024; + + if ((fd = hammer2_ioctl_handle(sel_path)) < 0) + return 1; + res = ioctl(fd, HAMMER2IOC_BULKFREE_SCAN, &bfi); + if (res) { + perror("ioctl"); + ecode = 1; + } + ecode = 0; + return ecode; +} diff --git a/sbin/hammer2/cmd_debug.c b/sbin/hammer2/cmd_debug.c index c9100da486..67b4e7253e 100644 --- a/sbin/hammer2/cmd_debug.c +++ b/sbin/hammer2/cmd_debug.c @@ -670,7 +670,7 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref, int dofreemap) media.bmdata[i].avail == 0) { continue; } - tabprintf(tab + 4, "%04d.%04x (avail=%5d) " + tabprintf(tab + 4, "%04d.%04x (avail=%7d) " "%08x %08x %08x %08x %08x %08x %08x %08x\n", i, media.bmdata[i].class, media.bmdata[i].avail, diff --git a/sbin/hammer2/hammer2.h b/sbin/hammer2/hammer2.h index cfb62a3c47..bc92042c90 100644 --- a/sbin/hammer2/hammer2.h +++ b/sbin/hammer2/hammer2.h @@ -142,6 +142,7 @@ int cmd_rsaenc(const char **keys, int nkeys); int cmd_rsadec(const char **keys, int nkeys); int cmd_setcomp(const char *comp_str, char **paths); int cmd_setcheck(const char *comp_str, char **paths); +int cmd_bulkfree(const char *dir_path); /* * Misc functions diff --git a/sbin/hammer2/main.c b/sbin/hammer2/main.c index 7da4fa4505..eaace8bf78 100644 --- a/sbin/hammer2/main.c +++ b/sbin/hammer2/main.c @@ -397,9 +397,17 @@ main(int ac, char **av) fprintf(stderr, "printinode: requires directory/file path\n"); usage(1); - } - else + } else { print_inode(av[1]); + } + } else if (strcmp(av[0], "bulkfree") == 0) { + if (ac != 2) { + fprintf(stderr, + "bulkfree: requires path to mount\n"); + usage(1); + } else { + ecode = cmd_bulkfree(av[1]); + } } else { fprintf(stderr, "Unrecognized command: %s\n", av[0]); usage(1); @@ -474,6 +482,8 @@ usage(int code) "Set check algo to crc64\n" " setsha192 path... " "Set check algo to sha192\n" + " bulkfree path... " + "Run bulkfree pass\n" ); exit(code); } -- 2.41.0 From 464659a3bd4716e96c69eecdf324d8fa37e16788 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 26 Jan 2015 18:07:05 -0800 Subject: [PATCH 14/16] hammer2 - Adjust TODO * Add bulkfree TODO items. --- sys/vfs/hammer2/TODO | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/sys/vfs/hammer2/TODO b/sys/vfs/hammer2/TODO index e5fbec593a..13c9a5b88e 100644 --- a/sys/vfs/hammer2/TODO +++ b/sys/vfs/hammer2/TODO @@ -1,4 +1,21 @@ +* bulkfree - sync between passes and enforce serialization of operation + +* bulkfree - signal check, allow interrupt + +* bulkfree - sub-passes when kernel memory block isn't large enough + +* bulkfree - limit kernel memory allocation for bmap space + +* bulkfree - must include any detached vnodes in scan so open unlinked files + are not ripped out from under the system. + +* bulkfree - must include all volume headers in scan so they can be used + for recovery or automatic snapshot retrieval. + +* bulkfree - snapshot duplicate sub-tree cache and tests needed to reduce + unnecessary re-scans. + * Currently the check code (bref.methods / crc, sha, etc) is being checked every single blasted time a chain is locked, even if the underlying buffer was previously checked for that chain. This needs an optimization to -- 2.41.0 From c5739aa6cd45a7da955214b8d5766d51b21e5031 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Tue, 27 Jan 2015 06:31:19 +0100 Subject: [PATCH 15/16] libusb: Sync with FreeBSD. --- lib/libusb/Makefile | 7 +++---- lib/libusb/libusb-1.0.pc | 4 ++-- lib/libusb/libusb.3 | 6 +++--- lib/libusb/libusb.h | 16 ++++++++++++++-- lib/libusb/libusb01.c | 4 +++- lib/libusb/libusb10.c | 5 ++++- lib/libusb/libusb20.3 | 2 +- lib/libusb/libusb20_desc.h | 8 +++++++- 8 files changed, 37 insertions(+), 15 deletions(-) diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile index 4cdb161f4b..ac011f9484 100644 --- a/lib/libusb/Makefile +++ b/lib/libusb/Makefile @@ -1,5 +1,5 @@ # -# $FreeBSD: head/lib/libusb/Makefile 260315 2014-01-05 10:41:43Z hselasky $ +# $FreeBSD: head/lib/libusb/Makefile 275024 2014-11-25 11:07:26Z bapt $ # # Makefile for the FreeBSD specific LibUSB 2.0 # @@ -15,12 +15,11 @@ INCS+= libusb20_desc.h MAN= libusb.3 libusb20.3 MKLINT= no NOGCCERROR= -PTHREAD_LIBS?= -lpthread -WARNS?= 2 +WARNS?= 3 DPADD= ${LIBPTHREAD} -LDADD= ${PTHREAD_LIBS} +LDADD= -lpthread MLINKS+= libusb.3 usb.3 diff --git a/lib/libusb/libusb-1.0.pc b/lib/libusb/libusb-1.0.pc index 1918212eac..411fd3983b 100644 --- a/lib/libusb/libusb-1.0.pc +++ b/lib/libusb/libusb-1.0.pc @@ -1,4 +1,4 @@ -# $FreeBSD: head/lib/libusb/libusb-1.0.pc 253637 2013-07-25 03:54:08Z rpaulo $ +# $FreeBSD: head/lib/libusb/libusb-1.0.pc 267110 2014-06-05 14:19:32Z emaste $ prefix=/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib @@ -6,6 +6,6 @@ includedir=${prefix}/include Name: libusb-1.0 Description: Library that abstracts ways to access USB devices (v1.0) -Version: 1.0.9 +Version: 1.0.13 Libs: -L${libdir} -lusb Cflags: -I${includedir} diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3 index de9b8ec9d0..8cf2b20bee 100644 --- a/lib/libusb/libusb.3 +++ b/lib/libusb/libusb.3 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: head/lib/libusb/libusb.3 260315 2014-01-05 10:41:43Z hselasky $ +.\" $FreeBSD: head/lib/libusb/libusb.3 277165 2015-01-14 06:46:25Z hselasky $ .\" .Dd January 5, 2014 .Dt LIBUSB 3 @@ -41,9 +41,9 @@ The .Nm library contains interfaces for directly managing a usb device. The current implementation supports v1.0 of the libusb API. -.Sh LIBRARY INITIALISATION / DEINITIALISATION +.Sh LIBRARY INITIALISATION AND DEINITIALISATION .Ft int -.Fn libusb_init libusb_context **ctx +.Fn libusb_init "libusb_context **ctx" This function initialises libusb. It must be called at the beginning of the program, before other libusb routines are used. diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h index 15cbe5843c..65ecc1ba0a 100644 --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -1,4 +1,4 @@ -/* $FreeBSD: head/lib/libusb/libusb.h 260315 2014-01-05 10:41:43Z hselasky $ */ +/* $FreeBSD: head/lib/libusb/libusb.h 277245 2015-01-16 12:11:01Z hselasky $ */ /*- * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. * @@ -33,6 +33,8 @@ #include #endif +#define LIBUSB_CALL + #ifdef __cplusplus extern "C" { #endif @@ -49,10 +51,18 @@ enum libusb_class_code { LIBUSB_CLASS_COMM = 2, LIBUSB_CLASS_HID = 3, LIBUSB_CLASS_PTP = 6, + LIBUSB_CLASS_IMAGE = 6, LIBUSB_CLASS_PRINTER = 7, LIBUSB_CLASS_MASS_STORAGE = 8, LIBUSB_CLASS_HUB = 9, LIBUSB_CLASS_DATA = 10, + LIBUSB_CLASS_SMART_CARD = 11, + LIBUSB_CLASS_CONTENT_SECURITY = 13, + LIBUSB_CLASS_VIDEO = 14, + LIBUSB_CLASS_PERSONAL_HEALTHCARE = 15, + LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + LIBUSB_CLASS_WIRELESS = 0xe0, + LIBUSB_CLASS_APPLICATION = 0xfe, LIBUSB_CLASS_VENDOR_SPEC = 0xff, }; @@ -118,6 +128,8 @@ enum libusb_standard_request { LIBUSB_REQUEST_GET_INTERFACE = 0x0A, LIBUSB_REQUEST_SET_INTERFACE = 0x0B, LIBUSB_REQUEST_SYNCH_FRAME = 0x0C, + LIBUSB_REQUEST_SET_SEL = 0x30, + LIBUSB_REQUEST_SET_ISOCH_DELAY = 0x31, }; enum libusb_request_type { @@ -197,7 +209,7 @@ enum libusb_log_level { LIBUSB_LOG_LEVEL_ERROR, LIBUSB_LOG_LEVEL_WARNING, LIBUSB_LOG_LEVEL_INFO, - LIBUSB_LOG_LEVEL_DEBUG + LIBUSB_LOG_LEVEL_DEBUG }; /* diff --git a/lib/libusb/libusb01.c b/lib/libusb/libusb01.c index cd31b55d0d..e858c038b7 100644 --- a/lib/libusb/libusb01.c +++ b/lib/libusb/libusb01.c @@ -1,4 +1,4 @@ -/* $FreeBSD: head/lib/libusb/libusb01.c 248236 2013-03-13 12:23:14Z hselasky $ */ +/* $FreeBSD: head/lib/libusb/libusb01.c 264344 2014-04-11 14:11:55Z hselasky $ */ /*- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. * @@ -127,6 +127,8 @@ usb_get_transfer_by_ep_no(usb_dev_handle * dev, uint8_t ep_no) bufsize = 256; } else if (speed == LIBUSB20_SPEED_FULL) { bufsize = 4096; + } else if (speed == LIBUSB20_SPEED_SUPER) { + bufsize = 65536; } else { bufsize = 16384; } diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index ffb34eac80..7c80c24878 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -1,4 +1,4 @@ -/* $FreeBSD: head/lib/libusb/libusb10.c 261224 2014-01-28 07:21:46Z hselasky $ */ +/* $FreeBSD: head/lib/libusb/libusb10.c 264344 2014-04-11 14:11:55Z hselasky $ */ /*- * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. * Copyright (c) 2009 Hans Petter Selasky. All rights reserved. @@ -935,6 +935,9 @@ libusb10_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) case LIBUSB20_SPEED_FULL: ret = 4096; break; + case LIBUSB20_SPEED_SUPER: + ret = 65536; + break; default: ret = 16384; break; diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3 index b1641607d8..75b7dd7946 100644 --- a/lib/libusb/libusb20.3 +++ b/lib/libusb/libusb20.3 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: head/lib/libusb/libusb20.3 250582 2013-05-12 22:22:12Z joel $ +.\" $FreeBSD: head/lib/libusb/libusb20.3 276294 2014-12-27 08:31:52Z joel $ .\" .Dd January 16, 2015 .Dt LIBUSB20 3 diff --git a/lib/libusb/libusb20_desc.h b/lib/libusb/libusb20_desc.h index efb534fd74..6bf586c855 100644 --- a/lib/libusb/libusb20_desc.h +++ b/lib/libusb/libusb20_desc.h @@ -1,4 +1,4 @@ -/* $FreeBSD: head/lib/libusb/libusb20_desc.h 248236 2013-03-13 12:23:14Z hselasky $ */ +/* $FreeBSD: head/lib/libusb/libusb20_desc.h 277245 2015-01-16 12:11:01Z hselasky $ */ /*- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. * Copyright (c) 2007-2008 Daniel Drake. All rights reserved. @@ -481,6 +481,12 @@ enum libusb20_standard_request { /** Set then report an endpoint's synchronization frame */ LIBUSB20_REQUEST_SYNCH_FRAME = 0x0C, + + /** Set U1 and U2 system exit latency */ + LIBUSB20_REQUEST_SET_SEL = 0x30, + + /** Set isochronous delay */ + LIBUSB20_REQUEST_SET_ISOCH_DELAY = 0x31, }; /** \ingroup misc -- 2.41.0 From 97703ab4089aa4b8a8e983ae799c772caa5cb759 Mon Sep 17 00:00:00 2001 From: Robin Hahling Date: Tue, 27 Jan 2015 06:56:42 +0100 Subject: [PATCH 16/16] openssh: Adjust DragonFly version to actual openssh p1 release date. --- crypto/openssh/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index 83a605c403..d8207e758f 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -5,5 +5,5 @@ #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE -#define SSH_VERSION_DRAGONFLY "DragonFly-20050123" +#define SSH_VERSION_DRAGONFLY "DragonFly-20141006" #define SSH_VERSION_HPN "_hpn14v5" -- 2.41.0