diff --git a/include/splat-ctl.h b/include/splat-ctl.h index 61c7e0e3c..6f15ba2e8 100644 --- a/include/splat-ctl.h +++ b/include/splat-ctl.h @@ -104,6 +104,7 @@ typedef struct splat_cmd { #define SPLAT_SUBSYSTEM_LIST 0x0c00 #define SPLAT_SUBSYSTEM_GENERIC 0x0d00 #define SPLAT_SUBSYSTEM_CRED 0x0e00 +#define SPLAT_SUBSYSTEM_ZLIB 0x0f00 #define SPLAT_SUBSYSTEM_UNKNOWN 0xff00 #endif /* _SPLAT_CTL_H */ diff --git a/module/splat/Makefile.in b/module/splat/Makefile.in index 724f824d5..2bf25c5b2 100644 --- a/module/splat/Makefile.in +++ b/module/splat/Makefile.in @@ -23,3 +23,4 @@ splat-objs += @top_srcdir@/module/splat/splat-atomic.o splat-objs += @top_srcdir@/module/splat/splat-list.o splat-objs += @top_srcdir@/module/splat/splat-generic.o splat-objs += @top_srcdir@/module/splat/splat-cred.o +splat-objs += @top_srcdir@/module/splat/splat-zlib.o diff --git a/module/splat/splat-ctl.c b/module/splat/splat-ctl.c index de72b805f..65ad8c113 100644 --- a/module/splat/splat-ctl.c +++ b/module/splat/splat-ctl.c @@ -632,6 +632,7 @@ splat_init(void) SPLAT_SUBSYSTEM_INIT(list); SPLAT_SUBSYSTEM_INIT(generic); SPLAT_SUBSYSTEM_INIT(cred); + SPLAT_SUBSYSTEM_INIT(zlib); dev = MKDEV(SPLAT_MAJOR, 0); if ((rc = register_chrdev_region(dev, SPLAT_MINORS, SPLAT_NAME))) @@ -680,6 +681,7 @@ splat_fini(void) cdev_del(&splat_cdev); unregister_chrdev_region(dev, SPLAT_MINORS); + SPLAT_SUBSYSTEM_FINI(zlib); SPLAT_SUBSYSTEM_FINI(cred); SPLAT_SUBSYSTEM_FINI(generic); SPLAT_SUBSYSTEM_FINI(list); diff --git a/module/splat/splat-internal.h b/module/splat/splat-internal.h index c42e08d6f..072abb8c7 100644 --- a/module/splat/splat-internal.h +++ b/module/splat/splat-internal.h @@ -63,6 +63,7 @@ #include #include #include +#include #include #include "spl-device.h" @@ -218,6 +219,7 @@ splat_subsystem_t *splat_atomic_init(void); splat_subsystem_t *splat_list_init(void); splat_subsystem_t *splat_generic_init(void); splat_subsystem_t *splat_cred_init(void); +splat_subsystem_t *splat_zlib_init(void); void splat_condvar_fini(splat_subsystem_t *); void splat_kmem_fini(splat_subsystem_t *); @@ -233,6 +235,7 @@ void splat_atomic_fini(splat_subsystem_t *); void splat_list_fini(splat_subsystem_t *); void splat_generic_fini(splat_subsystem_t *); void splat_cred_fini(splat_subsystem_t *); +void splat_zlib_fini(splat_subsystem_t *); int splat_condvar_id(void); int splat_kmem_id(void); @@ -248,5 +251,6 @@ int splat_atomic_id(void); int splat_list_id(void); int splat_generic_id(void); int splat_cred_id(void); +int splat_zlib_id(void); #endif /* _SPLAT_INTERNAL_H */ diff --git a/module/splat/splat-zlib.c b/module/splat/splat-zlib.c new file mode 100644 index 000000000..465d34091 --- /dev/null +++ b/module/splat/splat-zlib.c @@ -0,0 +1,162 @@ +/*****************************************************************************\ + * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. + * Copyright (C) 2007 The Regents of the University of California. + * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). + * Written by Brian Behlendorf . + * UCRL-CODE-235197 + * + * This file is part of the SPL, Solaris Porting Layer. + * For details, see . + * + * The SPL is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The SPL is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the SPL. If not, see . + ***************************************************************************** + * Solaris Porting LAyer Tests (SPLAT) Zlib Compression Tests. +\*****************************************************************************/ + +#include "splat-internal.h" + +#define SPLAT_ZLIB_NAME "zlib" +#define SPLAT_ZLIB_DESC "Zlib Compression Tests" + +#define SPLAT_ZLIB_TEST1_ID 0x0f01 +#define SPLAT_ZLIB_TEST1_NAME "compress/uncompress" +#define SPLAT_ZLIB_TEST1_DESC "Compress/Uncompress Test" + +#define BUFFER_SIZE (128 * 1024) + +static int +splat_zlib_test1_check(struct file *file, void *src, void *dst, void *chk, + int level) +{ + size_t dst_len = BUFFER_SIZE; + size_t chk_len = BUFFER_SIZE; + int rc; + + memset(dst, 0, BUFFER_SIZE); + memset(chk, 0, BUFFER_SIZE); + + rc = z_compress_level(dst, &dst_len, src, BUFFER_SIZE, level); + if (rc != Z_OK) { + splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, + "Failed level %d z_compress_level(), %d\n", level, rc); + return -EINVAL; + } + + rc = z_uncompress(chk, &chk_len, dst, dst_len); + if (rc != Z_OK) { + splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, + "Failed level %d z_uncompress(), %d\n", level, rc); + return -EINVAL; + } + + rc = memcmp(src, chk, BUFFER_SIZE); + if (rc) { + splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, + "Failed level %d memcmp()), %d\n", level, rc); + return -EINVAL; + } + + splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, + "Passed level %d, compressed %d bytes to %d bytes\n", + level, BUFFER_SIZE, (int)dst_len); + + return 0; +} + +/* + * Compress a buffer, uncompress the newly compressed buffer, then + * compare it to the original. Do this for all 9 compression levels. + */ +static int +splat_zlib_test1(struct file *file, void *arg) +{ + void *src = NULL, *dst = NULL, *chk = NULL; + int i, rc, level; + + src = vmalloc(BUFFER_SIZE); + if (src == NULL) { + rc = -ENOMEM; + goto out; + } + + dst = vmalloc(BUFFER_SIZE); + if (dst == NULL) { + rc = -ENOMEM; + goto out; + } + + chk = vmalloc(BUFFER_SIZE); + if (chk == NULL) { + rc = -ENOMEM; + goto out; + } + + /* Source buffer is a repeating 1024 byte random pattern. */ + random_get_pseudo_bytes(src, sizeof(uint8_t) * 1024); + for (i = 1; i < 128; i++) + memcpy(src + (i * 1024), src, 1024); + + for (level = 1; level <= 9; level++) + if ((rc = splat_zlib_test1_check(file, src, dst, chk, level))) + break; +out: + if (src) + vfree(src); + + if (dst) + vfree(dst); + + if (chk) + vfree(chk); + + return rc; +} + +splat_subsystem_t * +splat_zlib_init(void) +{ + splat_subsystem_t *sub; + + sub = kmalloc(sizeof(*sub), GFP_KERNEL); + if (sub == NULL) + return NULL; + + memset(sub, 0, sizeof(*sub)); + strncpy(sub->desc.name, SPLAT_ZLIB_NAME, SPLAT_NAME_SIZE); + strncpy(sub->desc.desc, SPLAT_ZLIB_DESC, SPLAT_DESC_SIZE); + INIT_LIST_HEAD(&sub->subsystem_list); + INIT_LIST_HEAD(&sub->test_list); + spin_lock_init(&sub->test_lock); + sub->desc.id = SPLAT_SUBSYSTEM_ZLIB; + + SPLAT_TEST_INIT(sub, SPLAT_ZLIB_TEST1_NAME, SPLAT_ZLIB_TEST1_DESC, + SPLAT_ZLIB_TEST1_ID, splat_zlib_test1); + + return sub; +} + +void +splat_zlib_fini(splat_subsystem_t *sub) +{ + ASSERT(sub); + + SPLAT_TEST_FINI(sub, SPLAT_ZLIB_TEST1_ID); + + kfree(sub); +} + +int +splat_zlib_id(void) { + return SPLAT_SUBSYSTEM_ZLIB; +} diff --git a/scripts/check.sh b/scripts/check.sh index b44b31333..4e4940685 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -62,6 +62,8 @@ if [ ! -f ${spl_module} ] || [ ! -f ${splat_module} ]; then die "Source tree must be built, run 'make'" fi +/sbin/modprobe zlib_deflate &>/dev/null + spl_module_params="spl_debug_mask=0xffffffff spl_debug_subsys=0xffffffff" echo "Loading ${spl_module}" /sbin/insmod ${spl_module} ${spl_module_params} || die "Failed to load ${spl_module}"