MFH
Sponsored by: The FreeBSD Foundation
This commit is contained in:
commit
aef2f6ad2e
@ -38,6 +38,8 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20160223: functionality from mkulzma(1) merged into mkuzip(1)
|
||||
OLD_FILES+=usr/bin/mkulzma
|
||||
# 20160211: Remove obsolete unbound-control-setup
|
||||
OLD_FILES+=usr/sbin/unbound-control-setup
|
||||
# 20160116: Update mandoc to cvs snapshot 20160116
|
||||
|
@ -242,7 +242,8 @@ preadbuffer(void)
|
||||
parsenleft = parselleft;
|
||||
parselleft = 0;
|
||||
} else /* *q == '\n' */ {
|
||||
parsenleft = q - parsenextc + 1;
|
||||
q++;
|
||||
parsenleft = q - parsenextc;
|
||||
parselleft -= parsenleft;
|
||||
}
|
||||
parsenleft--;
|
||||
|
@ -82,6 +82,7 @@ FILES+= only-redir2.0
|
||||
FILES+= only-redir3.0
|
||||
FILES+= only-redir4.0
|
||||
FILES+= pipe-not1.0
|
||||
FILES+= set-v1.0 set-v1.0.stderr
|
||||
FILES+= var-assign1.0
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
8
bin/sh/tests/parser/set-v1.0
Normal file
8
bin/sh/tests/parser/set-v1.0
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
${SH} <<\EOF
|
||||
echo one >&2
|
||||
set -v
|
||||
echo two >&2
|
||||
echo three >&2
|
||||
EOF
|
5
bin/sh/tests/parser/set-v1.0.stderr
Normal file
5
bin/sh/tests/parser/set-v1.0.stderr
Normal file
@ -0,0 +1,5 @@
|
||||
one
|
||||
echo two >&2
|
||||
two
|
||||
echo three >&2
|
||||
three
|
@ -253,6 +253,7 @@ hostapd_enable="NO" # Run hostap daemon.
|
||||
syslogd_enable="YES" # Run syslog daemon (or NO).
|
||||
syslogd_program="/usr/sbin/syslogd" # path to syslogd, if you want a different one.
|
||||
syslogd_flags="-s" # Flags to syslogd (if enabled).
|
||||
syslogd_oomprotect="YES" # Don't kill syslogd when swap space is exhausted.
|
||||
altlog_proglist="" # List of chrooted applicatioins in /var
|
||||
inetd_enable="NO" # Run the network daemon dispatcher (YES/NO).
|
||||
inetd_program="/usr/sbin/inetd" # path to inetd, if you want a different one.
|
||||
|
26
etc/rc.subr
26
etc/rc.subr
@ -45,6 +45,7 @@ _rc_subr_loaded="YES"
|
||||
SYSCTL="/sbin/sysctl"
|
||||
SYSCTL_N="${SYSCTL} -n"
|
||||
SYSCTL_W="${SYSCTL}"
|
||||
PROTECT="/usr/bin/protect"
|
||||
ID="/usr/bin/id"
|
||||
IDCMD="if [ -x $ID ]; then $ID -un; fi"
|
||||
PS="/bin/ps -ww"
|
||||
@ -755,6 +756,8 @@ check_startmsgs()
|
||||
#
|
||||
# ${name}_nice n Nice level to run ${command} at.
|
||||
#
|
||||
# ${name}_oomprotect n Don't kill ${command} when swap space is exhausted.
|
||||
#
|
||||
# ${name}_user n User to run ${command} as, using su(1) if not
|
||||
# using ${name}_chroot.
|
||||
# Requires /usr to be mounted.
|
||||
@ -944,7 +947,8 @@ run_rc_command()
|
||||
_nice=\$${name}_nice _user=\$${name}_user \
|
||||
_group=\$${name}_group _groups=\$${name}_groups \
|
||||
_fib=\$${name}_fib _env=\$${name}_env \
|
||||
_prepend=\$${name}_prepend _login_class=\${${name}_login_class:-daemon}
|
||||
_prepend=\$${name}_prepend _login_class=\${${name}_login_class:-daemon} \
|
||||
_oomprotect=\$${name}_oomprotect
|
||||
|
||||
if [ -n "$_user" ]; then # unset $_user if running as that user
|
||||
if [ "$_user" = "$(eval $IDCMD)" ]; then
|
||||
@ -1182,6 +1186,26 @@ $command $rc_flags $command_args"
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Apply protect(1) to the PID if ${name}_oomprotect is set.
|
||||
case "$rc_arg" in
|
||||
start)
|
||||
if [ -n "$_oomprotect" ]; then
|
||||
if [ -f "${PROTECT}" ]; then
|
||||
pid=$(check_process $command)
|
||||
case $_oomprotect in
|
||||
[Aa][Ll][Ll])
|
||||
${PROTECT} -i -p ${pid}
|
||||
;;
|
||||
[Yy][Ee][Ss])
|
||||
${PROTECT} -p ${pid}
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
return $_return
|
||||
done
|
||||
|
||||
|
@ -5,15 +5,17 @@
|
||||
PACKAGE=lib${LIB}
|
||||
LIB= sysdecode
|
||||
|
||||
SRCS= ioctl.c syscallnames.c utrace.c
|
||||
SRCS= errno.c ioctl.c syscallnames.c utrace.c
|
||||
INCS= sysdecode.h
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../sys
|
||||
|
||||
MAN+= sysdecode.3 \
|
||||
sysdecode_abi_to_freebsd_errno.3 \
|
||||
sysdecode_ioctlname.3 \
|
||||
sysdecode_syscallnames.3 \
|
||||
sysdecode_utrace.3
|
||||
MLINKS+= sysdecode_abi_to_freebsd_errno.3 sysdecode_freebsd_to_abi_errno.3
|
||||
|
||||
CLEANFILES= ioctl.c
|
||||
|
||||
|
209
lib/libsysdecode/errno.c
Normal file
209
lib/libsysdecode/errno.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 John H. Baldwin <jhb@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <sysdecode.h>
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
/*
|
||||
* Linux syscalls return negative errno's, we do positive and map them
|
||||
* Reference:
|
||||
* FreeBSD: src/sys/sys/errno.h
|
||||
* Linux: linux-2.6.17.8/include/asm-generic/errno-base.h
|
||||
* linux-2.6.17.8/include/asm-generic/errno.h
|
||||
*/
|
||||
static int bsd_to_linux_errno[ELAST + 1] = {
|
||||
-0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
|
||||
-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
|
||||
-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
|
||||
-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
|
||||
-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
|
||||
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
|
||||
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
|
||||
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
|
||||
-6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
|
||||
-72, -67, -71
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) || defined(__amd64__)
|
||||
#include <compat/cloudabi/cloudabi_syscalldefs.h>
|
||||
|
||||
static const int cloudabi_errno_table[] = {
|
||||
[CLOUDABI_E2BIG] = E2BIG,
|
||||
[CLOUDABI_EACCES] = EACCES,
|
||||
[CLOUDABI_EADDRINUSE] = EADDRINUSE,
|
||||
[CLOUDABI_EADDRNOTAVAIL] = EADDRNOTAVAIL,
|
||||
[CLOUDABI_EAFNOSUPPORT] = EAFNOSUPPORT,
|
||||
[CLOUDABI_EAGAIN] = EAGAIN,
|
||||
[CLOUDABI_EALREADY] = EALREADY,
|
||||
[CLOUDABI_EBADF] = EBADF,
|
||||
[CLOUDABI_EBADMSG] = EBADMSG,
|
||||
[CLOUDABI_EBUSY] = EBUSY,
|
||||
[CLOUDABI_ECANCELED] = ECANCELED,
|
||||
[CLOUDABI_ECHILD] = ECHILD,
|
||||
[CLOUDABI_ECONNABORTED] = ECONNABORTED,
|
||||
[CLOUDABI_ECONNREFUSED] = ECONNREFUSED,
|
||||
[CLOUDABI_ECONNRESET] = ECONNRESET,
|
||||
[CLOUDABI_EDEADLK] = EDEADLK,
|
||||
[CLOUDABI_EDESTADDRREQ] = EDESTADDRREQ,
|
||||
[CLOUDABI_EDOM] = EDOM,
|
||||
[CLOUDABI_EDQUOT] = EDQUOT,
|
||||
[CLOUDABI_EEXIST] = EEXIST,
|
||||
[CLOUDABI_EFAULT] = EFAULT,
|
||||
[CLOUDABI_EFBIG] = EFBIG,
|
||||
[CLOUDABI_EHOSTUNREACH] = EHOSTUNREACH,
|
||||
[CLOUDABI_EIDRM] = EIDRM,
|
||||
[CLOUDABI_EILSEQ] = EILSEQ,
|
||||
[CLOUDABI_EINPROGRESS] = EINPROGRESS,
|
||||
[CLOUDABI_EINTR] = EINTR,
|
||||
[CLOUDABI_EINVAL] = EINVAL,
|
||||
[CLOUDABI_EIO] = EIO,
|
||||
[CLOUDABI_EISCONN] = EISCONN,
|
||||
[CLOUDABI_EISDIR] = EISDIR,
|
||||
[CLOUDABI_ELOOP] = ELOOP,
|
||||
[CLOUDABI_EMFILE] = EMFILE,
|
||||
[CLOUDABI_EMLINK] = EMLINK,
|
||||
[CLOUDABI_EMSGSIZE] = EMSGSIZE,
|
||||
[CLOUDABI_EMULTIHOP] = EMULTIHOP,
|
||||
[CLOUDABI_ENAMETOOLONG] = ENAMETOOLONG,
|
||||
[CLOUDABI_ENETDOWN] = ENETDOWN,
|
||||
[CLOUDABI_ENETRESET] = ENETRESET,
|
||||
[CLOUDABI_ENETUNREACH] = ENETUNREACH,
|
||||
[CLOUDABI_ENFILE] = ENFILE,
|
||||
[CLOUDABI_ENOBUFS] = ENOBUFS,
|
||||
[CLOUDABI_ENODEV] = ENODEV,
|
||||
[CLOUDABI_ENOENT] = ENOENT,
|
||||
[CLOUDABI_ENOEXEC] = ENOEXEC,
|
||||
[CLOUDABI_ENOLCK] = ENOLCK,
|
||||
[CLOUDABI_ENOLINK] = ENOLINK,
|
||||
[CLOUDABI_ENOMEM] = ENOMEM,
|
||||
[CLOUDABI_ENOMSG] = ENOMSG,
|
||||
[CLOUDABI_ENOPROTOOPT] = ENOPROTOOPT,
|
||||
[CLOUDABI_ENOSPC] = ENOSPC,
|
||||
[CLOUDABI_ENOSYS] = ENOSYS,
|
||||
[CLOUDABI_ENOTCONN] = ENOTCONN,
|
||||
[CLOUDABI_ENOTDIR] = ENOTDIR,
|
||||
[CLOUDABI_ENOTEMPTY] = ENOTEMPTY,
|
||||
[CLOUDABI_ENOTRECOVERABLE] = ENOTRECOVERABLE,
|
||||
[CLOUDABI_ENOTSOCK] = ENOTSOCK,
|
||||
[CLOUDABI_ENOTSUP] = ENOTSUP,
|
||||
[CLOUDABI_ENOTTY] = ENOTTY,
|
||||
[CLOUDABI_ENXIO] = ENXIO,
|
||||
[CLOUDABI_EOVERFLOW] = EOVERFLOW,
|
||||
[CLOUDABI_EOWNERDEAD] = EOWNERDEAD,
|
||||
[CLOUDABI_EPERM] = EPERM,
|
||||
[CLOUDABI_EPIPE] = EPIPE,
|
||||
[CLOUDABI_EPROTO] = EPROTO,
|
||||
[CLOUDABI_EPROTONOSUPPORT] = EPROTONOSUPPORT,
|
||||
[CLOUDABI_EPROTOTYPE] = EPROTOTYPE,
|
||||
[CLOUDABI_ERANGE] = ERANGE,
|
||||
[CLOUDABI_EROFS] = EROFS,
|
||||
[CLOUDABI_ESPIPE] = ESPIPE,
|
||||
[CLOUDABI_ESRCH] = ESRCH,
|
||||
[CLOUDABI_ESTALE] = ESTALE,
|
||||
[CLOUDABI_ETIMEDOUT] = ETIMEDOUT,
|
||||
[CLOUDABI_ETXTBSY] = ETXTBSY,
|
||||
[CLOUDABI_EXDEV] = EXDEV,
|
||||
[CLOUDABI_ENOTCAPABLE] = ENOTCAPABLE,
|
||||
};
|
||||
#endif
|
||||
|
||||
int
|
||||
sysdecode_abi_to_freebsd_errno(enum sysdecode_abi abi, int error)
|
||||
{
|
||||
|
||||
switch (abi) {
|
||||
case SYSDECODE_ABI_FREEBSD:
|
||||
case SYSDECODE_ABI_FREEBSD32:
|
||||
return (error);
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
case SYSDECODE_ABI_LINUX:
|
||||
case SYSDECODE_ABI_LINUX32: {
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* This is imprecise since it returns the first
|
||||
* matching errno.
|
||||
*/
|
||||
for (i = 0; i < nitems(bsd_to_linux_errno); i++) {
|
||||
if (error == bsd_to_linux_errno[i])
|
||||
return (i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(__aarch64__) || defined(__amd64__)
|
||||
case SYSDECODE_ABI_CLOUDABI64:
|
||||
if (error >= 0 &&
|
||||
(unsigned int)error < nitems(cloudabi_errno_table))
|
||||
return (cloudabi_errno_table[error]);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (INT_MAX);
|
||||
}
|
||||
|
||||
int
|
||||
sysdecode_freebsd_to_abi_errno(enum sysdecode_abi abi, int error)
|
||||
{
|
||||
|
||||
switch (abi) {
|
||||
case SYSDECODE_ABI_FREEBSD:
|
||||
case SYSDECODE_ABI_FREEBSD32:
|
||||
return (error);
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
case SYSDECODE_ABI_LINUX:
|
||||
case SYSDECODE_ABI_LINUX32:
|
||||
if (error >= 0 && error <= ELAST)
|
||||
return (bsd_to_linux_errno[error]);
|
||||
break;
|
||||
#endif
|
||||
#if defined(__aarch64__) || defined(__amd64__)
|
||||
case SYSDECODE_ABI_CLOUDABI64: {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nitems(cloudabi_errno_table); i++) {
|
||||
if (error == cloudabi_errno_table[i])
|
||||
return (i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (INT_MAX);
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ Supported on aarch64 and amd64.
|
||||
A placeholder for use when the ABI is not known.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sysdecode_abi_to_freebsd_errno 3 ,
|
||||
.Xr sysdecode_ioctlname 3 ,
|
||||
.Xr sysdecode_syscallnames 3 ,
|
||||
.Xr sysdecode_utrace 3
|
||||
|
@ -38,6 +38,8 @@ enum sysdecode_abi {
|
||||
SYSDECODE_ABI_CLOUDABI64
|
||||
};
|
||||
|
||||
int sysdecode_abi_to_freebsd_errno(enum sysdecode_abi _abi, int _error);
|
||||
int sysdecode_freebsd_to_abi_errno(enum sysdecode_abi _abi, int _error);
|
||||
const char *sysdecode_ioctlname(unsigned long _val);
|
||||
const char *sysdecode_syscallname(enum sysdecode_abi _abi, unsigned int _code);
|
||||
int sysdecode_utrace(FILE *_fp, void *_buf, size_t _len);
|
||||
|
94
lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3
Normal file
94
lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3
Normal file
@ -0,0 +1,94 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 23, 2016
|
||||
.Dt sysdecode_abi_to_freebsd_errno 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sysdecode_abi_to_freebsd_errno ,
|
||||
.Nm sysdecode_freebsd_to_abi_errno
|
||||
.Nd translate error numbers between process ABIs
|
||||
.Sh LIBRARY
|
||||
.Lb libsysdecode
|
||||
.Sh SYNOPSIS
|
||||
.Ft int
|
||||
.Fn sysdecode_abi_to_freebsd_errno "enum sysdecode_abi abi" "int error"
|
||||
.Ft int
|
||||
.Fn sysdecode_freebsd_to_abi_errno "enum sysdecode_abi abi" "int error"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sysdecode_abi_to_freebsd_errno
|
||||
function returns the native
|
||||
.Xr errno 3
|
||||
value that corresponds to the error indicated by
|
||||
.Fa error
|
||||
for the process ABI
|
||||
.Fa abi .
|
||||
If
|
||||
.Fa error
|
||||
does not identify a valid error for
|
||||
.Fa abi ,
|
||||
.Dv INT_MAX
|
||||
is returned.
|
||||
.Pp
|
||||
The
|
||||
.Fn sysdecode_freebsd_to_abi_errno
|
||||
function the error value for the process ABI
|
||||
.Fa abi
|
||||
that corresponds to the native
|
||||
.Xr errno 3
|
||||
value
|
||||
.Fa error .
|
||||
If
|
||||
.Fa error
|
||||
does not identify a valid
|
||||
.Xr errno 3
|
||||
error,
|
||||
.Dv INT_MAX
|
||||
is returned.
|
||||
.Pp
|
||||
Note that the mappings between native
|
||||
.Xr errno 3
|
||||
values and errors for other ABIs are not exhaustive.
|
||||
If a mapping does not exist,
|
||||
these functions return
|
||||
.Dv INT_MAX .
|
||||
In addition, multiple error values in one ABI may map to a single
|
||||
error in another ABI.
|
||||
.Sh RETURN VALUES
|
||||
These functions return an error value on success or
|
||||
.Dv INT_MAX
|
||||
if
|
||||
.Fa error
|
||||
is not valid.
|
||||
.Pp
|
||||
For the list of supported ABIs,
|
||||
see
|
||||
.Xr sysdecode 3 .
|
||||
.Sh SEE ALSO
|
||||
.Xr sysdecode 3 ,
|
||||
.Xr sysdecode_syscallnames 3
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 24, 2016
|
||||
.Dd January 30, 2016
|
||||
.Dt sysdecode_syscallnames 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -64,4 +64,5 @@ or
|
||||
.Fa ABI
|
||||
is invalid .
|
||||
.Sh SEE ALSO
|
||||
.Xr sysdecode 3
|
||||
.Xr sysdecode 3 ,
|
||||
.Xr sysdecode_abi_to_freebsd_errno 3
|
||||
|
@ -167,7 +167,6 @@ MAN= aac.4 \
|
||||
geom_fox.4 \
|
||||
geom_linux_lvm.4 \
|
||||
geom_map.4 \
|
||||
geom_uncompress.4 \
|
||||
geom_uzip.4 \
|
||||
gif.4 \
|
||||
gpio.4 \
|
||||
|
@ -78,7 +78,7 @@ or by using
|
||||
0 DISK cfid0 8388608 4 hd 0 sc 0
|
||||
1 MAP map/config 131072 4 i 5 o 8257536 entry 0 dsize 131072
|
||||
1 MAP map/rootfs 6881280 4 i 4 o 1376256 entry 0 dsize 6881280
|
||||
2 UNCOMPRESS map/rootfs.uncompress 18677760 512
|
||||
2 UZIP map/rootfs.uzip 18677760 512
|
||||
1 MAP map/kernel 1114112 4 i 3 o 262144 entry 0 dsize 1114112
|
||||
1 MAP map/upgrade 7995392 4 i 2 o 262144 entry 0 dsize 7995392
|
||||
1 MAP map/factory 65536 4 i 1 o 196608 entry 0 dsize 65536
|
||||
|
@ -1,118 +0,0 @@
|
||||
.\" Copyright (c) 2006, Ceri Davies <ceri@FreeBSD.org>
|
||||
.\" Copyright (c) 2014, Luiz Otavio O Souza <loos@FreeBSD.org>
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 9, 2014
|
||||
.Dt GEOM_UNCOMPRESS 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm geom_uncompress
|
||||
.Nd "GEOM based compressed disk images"
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel, place the following line in your
|
||||
kernel configuration file:
|
||||
.Bd -ragged -offset indent
|
||||
.Cd "options GEOM_UNCOMPRESS"
|
||||
.Ed
|
||||
.Pp
|
||||
Alternatively, to load the driver as a module at boot time, place the
|
||||
following line in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
geom_uncompress_load="YES"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
framework provides support for compressed read-only disk images.
|
||||
This allows significant storage savings at the expense of a little CPU
|
||||
time on each read.
|
||||
Data written in the GEOM label area allows
|
||||
.Nm
|
||||
to detect compressed images which have been created with
|
||||
.Xr mkulzma 8
|
||||
or
|
||||
.Xr mkuzip 8
|
||||
and presented to the kernel as a logical disk device via
|
||||
.Xr md 4 .
|
||||
.Nm
|
||||
creates a unique
|
||||
.Pa md#.uncompress
|
||||
device for each image.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
device is subsequently used by the
|
||||
.Fx
|
||||
kernel to access the disk images.
|
||||
The
|
||||
.Nm
|
||||
driver does not allow write operations to the underlying disk image.
|
||||
To check which
|
||||
.Xr md 4
|
||||
devices match a given
|
||||
.Nm
|
||||
device:
|
||||
.Bd -literal -offset indent
|
||||
# geom uncompress list
|
||||
Geom name: md0.uncompress
|
||||
Providers:
|
||||
1. Name: md0.uncompress
|
||||
Mediasize: 52428800 (50M)
|
||||
Sectorsize: 512
|
||||
Mode: r1w0e0
|
||||
Consumers:
|
||||
1. Name: md0
|
||||
Mediasize: 20864000 (20M)
|
||||
Sectorsize: 512
|
||||
Mode: r1w0e0
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr GEOM 4 ,
|
||||
.Xr md 4 ,
|
||||
.Xr geom 8 ,
|
||||
.Xr mkulzma 8 ,
|
||||
.Xr mkuzip 8
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Max Khon Aq Mt fjoe@FreeBSD.org
|
||||
as
|
||||
.Xr geom_uzip 4 .
|
||||
.An Aleksandr Rybalko Aq Mt ray@FreeBSD.org
|
||||
copied it over as
|
||||
.Nm
|
||||
and added LZMA functionality .
|
||||
This manual page was written by
|
||||
.An Ceri Davies Aq Mt ceri@FreeBSD.org
|
||||
for the
|
||||
.Xr geom_uzip 4 ,
|
||||
and modified by
|
||||
.An Luiz Otavio O Souza Aq Mt loos@FreeBSD.org
|
||||
to match
|
||||
.Nm .
|
@ -30,7 +30,7 @@
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm geom_uzip
|
||||
.Nd "GEOM based compressed disk images"
|
||||
.Nd "GEOM based compressed disk images and partitions"
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel,
|
||||
place the following line in your
|
||||
@ -51,7 +51,7 @@ The
|
||||
framework provides support for compressed read-only
|
||||
disk images.
|
||||
This allows significant storage savings at the expense of
|
||||
a little CPU time on each read.
|
||||
a some CPU time on each read.
|
||||
Data written in the GEOM label area allows
|
||||
.Nm
|
||||
to detect compressed images which have been created with
|
||||
@ -63,17 +63,53 @@ creates a unique
|
||||
.Pa md#.uzip
|
||||
device for each image.
|
||||
.Pp
|
||||
.Nm
|
||||
is not limited to supporting only
|
||||
.Xr md 4
|
||||
images.
|
||||
The image can also reside on a block device.
|
||||
.Pq For example, a disk, USB flash drive, DVD-ROM, etc.
|
||||
The appropriate device node will appear with the
|
||||
.Pa .uzip
|
||||
suffix.
|
||||
.Bd -literal -offset indent
|
||||
# gpart show da0
|
||||
=> 0 7833600 da0 BSD (3.7G)
|
||||
0 2097152 1 freebsd-ufs (1.0G)
|
||||
2097152 5736448 - free - (2.7G)
|
||||
# gpart add -t freebsd-ufs -s 1G da0
|
||||
da0b added
|
||||
# dd if=/tmp/20160217_dcomp_zcomp.uzip bs=256k of=/dev/da0b
|
||||
3190+1 records in
|
||||
3190+1 records out
|
||||
836331008 bytes transferred in 111.021489 secs (7533055 bytes/sec)
|
||||
# fsck -t ffs /dev/da0b.uzip
|
||||
** /dev/da0b.uzip (NO WRITE)
|
||||
** Last Mounted on /mnt
|
||||
** Phase 1 - Check Blocks and Sizes
|
||||
** Phase 2 - Check Pathnames
|
||||
** Phase 3 - Check Connectivity
|
||||
** Phase 4 - Check Reference Counts
|
||||
** Phase 5 - Check Cyl groups
|
||||
97455 files, 604242 used, 184741 free (2349 frags, 22799 blocks,
|
||||
0.3% fragmentation)
|
||||
# mount -o ro /dev/da0b.uzip /mnt
|
||||
# df /dev/da0b.uzip
|
||||
Filesystem 1K-blocks Used Avail Capacity Mounted on
|
||||
/dev/da0b.uzip 3155932 2416968 738964 77% /mnt
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
device is subsequently used by the
|
||||
device is subsequently used by
|
||||
.Fx
|
||||
kernel to access the disk images.
|
||||
kernel to access the uncompressed data.
|
||||
The
|
||||
.Nm
|
||||
driver does not allow write operations to the underlying disk image.
|
||||
To check which
|
||||
.Xr md 4
|
||||
devices match a given
|
||||
.Dq providers
|
||||
match a given
|
||||
.Nm
|
||||
device:
|
||||
.Bd -literal -offset indent
|
||||
@ -83,13 +119,44 @@ Providers:
|
||||
1. Name: md1.uzip
|
||||
Mediasize: 22003712 (21M)
|
||||
Sectorsize: 512
|
||||
Mode: r1w0e1
|
||||
Consumers:
|
||||
1. Name: md1
|
||||
Mediasize: 9563648 (9.1M)
|
||||
Sectorsize: 512
|
||||
Mode: r1w0e1
|
||||
|
||||
Geom name: da0b.uzip
|
||||
Providers:
|
||||
1. Name: da0b.uzip
|
||||
Mediasize: 3355443200 (3.1G)
|
||||
Sectorsize: 512
|
||||
Consumers:
|
||||
1. Name: da0b
|
||||
Mediasize: 1073741824 (1.0G)
|
||||
Sectorsize: 512
|
||||
.Ed
|
||||
.Pp
|
||||
.Nm
|
||||
allows mounting the root file system from a compressed disk partition by
|
||||
setting the
|
||||
.Dv vfs.root.mountfrom
|
||||
tunable.
|
||||
See
|
||||
.Xr loader.conf 5
|
||||
for details.
|
||||
.Sh DIAGNOSTICS
|
||||
Several flags are provided for tracing
|
||||
.Nm
|
||||
I/O operations and TOC parsing via the following sysctls.
|
||||
.Bl -tag -width indent
|
||||
.It Va kern.geom.uzip.debug
|
||||
Log level.
|
||||
Zero disables logging.
|
||||
Higher values enable more verbose debug logging for
|
||||
.Nm .
|
||||
Supported levels are from 0 (no logging) to 4 (maximum amount of logging).
|
||||
.It Va kern.geom.uzip.debug_block
|
||||
Log operations involving compressed cluster number.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr GEOM 4 ,
|
||||
.Xr md 4 ,
|
||||
@ -101,5 +168,12 @@ The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Max Khon Aq Mt fjoe@FreeBSD.org .
|
||||
The block de-duplication code as well as some
|
||||
.Nm
|
||||
driver optimizations have been contributed by
|
||||
.An Maxim Sobolev Aq Mt sobomax@FreeBSD.org .
|
||||
The LZMA decompression support and CLOOP 3.0 support have been added by
|
||||
.An Aleksandr Rybalko Aq Mt ray@FreeBSD.org .
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Ceri Davies Aq Mt ceri@FreeBSD.org .
|
||||
|
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 12, 2014
|
||||
.Dd February 4, 2016
|
||||
.Dt RC.SUBR 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -604,6 +604,16 @@ as.
|
||||
Only supported after
|
||||
.Pa /usr
|
||||
is mounted.
|
||||
.It Va ${name}_oomprotect
|
||||
.Xr protect 1
|
||||
.Va command
|
||||
from being killed when swap space is exhausted.
|
||||
If
|
||||
.Em YES
|
||||
is used, no child processes are protected.
|
||||
If
|
||||
.Em ALL ,
|
||||
protect all child processes.
|
||||
.It Va ${name}_program
|
||||
Full path to the command.
|
||||
Overrides
|
||||
|
@ -238,7 +238,6 @@ geom_nop_load="NO" # Transparent disk driver (see gnop(8))
|
||||
geom_raid3_load="NO" # RAID3 disk driver (see graid3(8))
|
||||
geom_shsec_load="NO" # Shared secret disk driver (see gshsec(8))
|
||||
geom_stripe_load="NO" # RAID0 disk driver (see gstripe(8))
|
||||
geom_uncompress_load="NO" # Compressed disk images driver (see mkulzma(8))
|
||||
geom_uzip_load="NO" # Compressed disk images driver (see mkuzip(8))
|
||||
geom_vinum_load="NO" # Concatenated/mirror/raid driver (see vinum(4))
|
||||
|
||||
|
@ -3081,23 +3081,25 @@ geom/raid3/g_raid3.c optional geom_raid3
|
||||
geom/raid3/g_raid3_ctl.c optional geom_raid3
|
||||
geom/shsec/g_shsec.c optional geom_shsec
|
||||
geom/stripe/g_stripe.c optional geom_stripe
|
||||
geom/uncompress/g_uncompress.c optional geom_uncompress
|
||||
contrib/xz-embedded/freebsd/xz_malloc.c \
|
||||
optional xz_embedded | geom_uncompress \
|
||||
optional xz_embedded | geom_uzip \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_crc32.c \
|
||||
optional xz_embedded | geom_uncompress \
|
||||
optional xz_embedded | geom_uzip \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_dec_bcj.c \
|
||||
optional xz_embedded | geom_uncompress \
|
||||
optional xz_embedded | geom_uzip \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c \
|
||||
optional xz_embedded | geom_uncompress \
|
||||
optional xz_embedded | geom_uzip \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_dec_stream.c \
|
||||
optional xz_embedded | geom_uncompress \
|
||||
optional xz_embedded | geom_uzip \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/"
|
||||
geom/uzip/g_uzip.c optional geom_uzip
|
||||
geom/uzip/g_uzip_lzma.c optional geom_uzip
|
||||
geom/uzip/g_uzip_wrkthr.c optional geom_uzip
|
||||
geom/uzip/g_uzip_zlib.c optional geom_uzip
|
||||
geom/vinum/geom_vinum.c optional geom_vinum
|
||||
geom/vinum/geom_vinum_create.c optional geom_vinum
|
||||
geom/vinum/geom_vinum_drive.c optional geom_vinum
|
||||
@ -3455,7 +3457,7 @@ libkern/strvalid.c standard
|
||||
libkern/timingsafe_bcmp.c standard
|
||||
libkern/zlib.c optional crypto | geom_uzip | ipsec | \
|
||||
mxge | netgraph_deflate | \
|
||||
ddb_ctf | gzio | geom_uncompress
|
||||
ddb_ctf | gzio
|
||||
net/altq/altq_cbq.c optional altq
|
||||
net/altq/altq_cdnr.c optional altq
|
||||
net/altq/altq_codel.c optional altq
|
||||
|
@ -434,9 +434,7 @@ acpi_ec_probe(device_t dev)
|
||||
params->gpe_bit, (params->glk) ? ", GLK" : "",
|
||||
ecdt ? ", ECDT" : "");
|
||||
device_set_desc_copy(dev, desc);
|
||||
}
|
||||
|
||||
if (ret > 0 && params)
|
||||
} else
|
||||
free(params, M_TEMP);
|
||||
if (buf.Pointer)
|
||||
AcpiOsFree(buf.Pointer);
|
||||
|
@ -597,23 +597,28 @@ acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle)
|
||||
{
|
||||
|
||||
ACPI_SERIAL_BEGIN(video_output);
|
||||
if (vo->vo_levels != NULL)
|
||||
if (vo->vo_levels != NULL) {
|
||||
AcpiRemoveNotifyHandler(vo->handle, ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_vo_notify_handler);
|
||||
AcpiOsFree(vo->vo_levels);
|
||||
vo->vo_levels = NULL;
|
||||
}
|
||||
vo->handle = handle;
|
||||
vo->vo_numlevels = vo_get_brightness_levels(handle, &vo->vo_levels);
|
||||
if (vo->vo_numlevels >= 2) {
|
||||
if (vo->vo_fullpower == -1
|
||||
|| acpi_video_vo_check_level(vo, vo->vo_fullpower) != 0)
|
||||
if (vo->vo_fullpower == -1 ||
|
||||
acpi_video_vo_check_level(vo, vo->vo_fullpower) != 0) {
|
||||
/* XXX - can't deal with rebinding... */
|
||||
vo->vo_fullpower = vo->vo_levels[BCL_FULLPOWER];
|
||||
if (vo->vo_economy == -1
|
||||
|| acpi_video_vo_check_level(vo, vo->vo_economy) != 0)
|
||||
}
|
||||
if (vo->vo_economy == -1 ||
|
||||
acpi_video_vo_check_level(vo, vo->vo_economy) != 0) {
|
||||
/* XXX - see above. */
|
||||
vo->vo_economy = vo->vo_levels[BCL_ECONOMY];
|
||||
}
|
||||
if (vo->vo_levels != NULL)
|
||||
}
|
||||
AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_vo_notify_handler, vo);
|
||||
}
|
||||
ACPI_SERIAL_END(video_output);
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,8 @@ static int ixl_init_msix(struct ixl_pf *);
|
||||
static void ixl_configure_msix(struct ixl_pf *);
|
||||
static void ixl_configure_itr(struct ixl_pf *);
|
||||
static void ixl_configure_legacy(struct ixl_pf *);
|
||||
static void ixl_init_taskqueues(struct ixl_pf *);
|
||||
static void ixl_free_taskqueues(struct ixl_pf *);
|
||||
static void ixl_free_pci_resources(struct ixl_pf *);
|
||||
static void ixl_local_timer(void *);
|
||||
static int ixl_setup_interface(device_t, struct ixl_vsi *);
|
||||
@ -642,7 +644,7 @@ ixl_attach(device_t dev)
|
||||
else
|
||||
error = ixl_assign_vsi_legacy(pf);
|
||||
if (error)
|
||||
goto err_late;
|
||||
goto err_mac_hmc;
|
||||
|
||||
if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
|
||||
(hw->aq.fw_maj_ver < 4)) {
|
||||
@ -667,7 +669,7 @@ ixl_attach(device_t dev)
|
||||
error = ixl_switch_config(pf);
|
||||
if (error) {
|
||||
device_printf(dev, "Initial switch config failed: %d\n", error);
|
||||
goto err_mac_hmc;
|
||||
goto err_late;
|
||||
}
|
||||
|
||||
/* Limit phy interrupts to link and modules failure */
|
||||
@ -680,6 +682,9 @@ ixl_attach(device_t dev)
|
||||
bus = ixl_get_bus_info(hw, dev);
|
||||
i40e_set_pci_config_data(hw, bus);
|
||||
|
||||
/* Initialize taskqueues */
|
||||
ixl_init_taskqueues(pf);
|
||||
|
||||
/* Initialize statistics */
|
||||
ixl_pf_reset_stats(pf);
|
||||
ixl_update_stats_counters(pf);
|
||||
@ -748,7 +753,6 @@ ixl_detach(device_t dev)
|
||||
struct ixl_pf *pf = device_get_softc(dev);
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
struct ixl_vsi *vsi = &pf->vsi;
|
||||
struct ixl_queue *que = vsi->queues;
|
||||
i40e_status status;
|
||||
#ifdef PCI_IOV
|
||||
int error;
|
||||
@ -777,13 +781,7 @@ ixl_detach(device_t dev)
|
||||
IXL_PF_UNLOCK(pf);
|
||||
}
|
||||
|
||||
for (int i = 0; i < vsi->num_queues; i++, que++) {
|
||||
if (que->tq) {
|
||||
taskqueue_drain(que->tq, &que->task);
|
||||
taskqueue_drain(que->tq, &que->tx_task);
|
||||
taskqueue_free(que->tq);
|
||||
}
|
||||
}
|
||||
ixl_free_taskqueues(pf);
|
||||
|
||||
/* Shutdown LAN HMC */
|
||||
status = i40e_shutdown_lan_hmc(hw);
|
||||
@ -1990,6 +1988,58 @@ ixl_assign_vsi_legacy(struct ixl_pf *pf)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ixl_init_taskqueues(struct ixl_pf *pf)
|
||||
{
|
||||
struct ixl_vsi *vsi = &pf->vsi;
|
||||
struct ixl_queue *que = vsi->queues;
|
||||
device_t dev = pf->dev;
|
||||
|
||||
/* Tasklet for Admin Queue */
|
||||
TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf);
|
||||
#ifdef PCI_IOV
|
||||
/* VFLR Tasklet */
|
||||
TASK_INIT(&pf->vflr_task, 0, ixl_handle_vflr, pf);
|
||||
#endif
|
||||
|
||||
/* Create and start PF taskqueue */
|
||||
pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT,
|
||||
taskqueue_thread_enqueue, &pf->tq);
|
||||
taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq",
|
||||
device_get_nameunit(dev));
|
||||
|
||||
/* Create queue tasks and start queue taskqueues */
|
||||
for (int i = 0; i < vsi->num_queues; i++, que++) {
|
||||
TASK_INIT(&que->tx_task, 0, ixl_deferred_mq_start, que);
|
||||
TASK_INIT(&que->task, 0, ixl_handle_que, que);
|
||||
que->tq = taskqueue_create_fast("ixl_que", M_NOWAIT,
|
||||
taskqueue_thread_enqueue, &que->tq);
|
||||
#ifdef RSS
|
||||
CPU_SETOF(cpu_id, &cpu_mask);
|
||||
taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET,
|
||||
&cpu_mask, "%s (bucket %d)",
|
||||
device_get_nameunit(dev), cpu_id);
|
||||
#else
|
||||
taskqueue_start_threads(&que->tq, 1, PI_NET,
|
||||
"%s (que %d)", device_get_nameunit(dev), que->me);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
ixl_free_taskqueues(struct ixl_pf *pf)
|
||||
{
|
||||
struct ixl_vsi *vsi = &pf->vsi;
|
||||
struct ixl_queue *que = vsi->queues;
|
||||
|
||||
if (pf->tq)
|
||||
taskqueue_free(pf->tq);
|
||||
for (int i = 0; i < vsi->num_queues; i++, que++) {
|
||||
if (que->tq)
|
||||
taskqueue_free(que->tq);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
@ -2028,17 +2078,6 @@ ixl_assign_vsi_msix(struct ixl_pf *pf)
|
||||
}
|
||||
bus_describe_intr(dev, pf->res, pf->tag, "aq");
|
||||
pf->admvec = vector;
|
||||
/* Tasklet for Admin Queue */
|
||||
TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf);
|
||||
|
||||
#ifdef PCI_IOV
|
||||
TASK_INIT(&pf->vflr_task, 0, ixl_handle_vflr, pf);
|
||||
#endif
|
||||
|
||||
pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT,
|
||||
taskqueue_thread_enqueue, &pf->tq);
|
||||
taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq",
|
||||
device_get_nameunit(pf->dev));
|
||||
++vector;
|
||||
|
||||
/* Now set up the stations */
|
||||
@ -2069,19 +2108,6 @@ ixl_assign_vsi_msix(struct ixl_pf *pf)
|
||||
#endif
|
||||
bus_bind_intr(dev, que->res, cpu_id);
|
||||
que->msix = vector;
|
||||
TASK_INIT(&que->tx_task, 0, ixl_deferred_mq_start, que);
|
||||
TASK_INIT(&que->task, 0, ixl_handle_que, que);
|
||||
que->tq = taskqueue_create_fast("ixl_que", M_NOWAIT,
|
||||
taskqueue_thread_enqueue, &que->tq);
|
||||
#ifdef RSS
|
||||
CPU_SETOF(cpu_id, &cpu_mask);
|
||||
taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET,
|
||||
&cpu_mask, "%s (bucket %d)",
|
||||
device_get_nameunit(dev), cpu_id);
|
||||
#else
|
||||
taskqueue_start_threads(&que->tq, 1, PI_NET,
|
||||
"%s que", device_get_nameunit(dev));
|
||||
#endif
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -2144,9 +2170,15 @@ ixl_init_msix(struct ixl_pf *pf)
|
||||
/* Figure out a reasonable auto config value */
|
||||
queues = (mp_ncpus > (available - 1)) ? (available - 1) : mp_ncpus;
|
||||
|
||||
/* Override with hardcoded value if sane */
|
||||
/* Override with hardcoded value if it's less than autoconfig count */
|
||||
if ((ixl_max_queues != 0) && (ixl_max_queues <= queues))
|
||||
queues = ixl_max_queues;
|
||||
else if ((ixl_max_queues != 0) && (ixl_max_queues > queues))
|
||||
device_printf(dev, "ixl_max_queues > # of cpus, using "
|
||||
"autoconfig amount...\n");
|
||||
/* Or limit maximum auto-configured queues to 8 */
|
||||
else if ((ixl_max_queues == 0) && (queues > 8))
|
||||
queues = 8;
|
||||
|
||||
#ifdef RSS
|
||||
/* If we're doing RSS, clamp at the number of RSS buckets */
|
||||
@ -2880,7 +2912,6 @@ ixl_initialize_vsi(struct ixl_vsi *vsi)
|
||||
device_printf(dev, "Fail in init_rx_ring %d\n", i);
|
||||
break;
|
||||
}
|
||||
wr32(vsi->hw, I40E_QRX_TAIL(que->me), 0);
|
||||
#ifdef DEV_NETMAP
|
||||
/* preserve queue */
|
||||
if (vsi->ifp->if_capenable & IFCAP_NETMAP) {
|
||||
|
@ -390,7 +390,6 @@ ixl_xmit(struct ixl_queue *que, struct mbuf **m_headp)
|
||||
++txr->total_packets;
|
||||
wr32(hw, txr->tail, i);
|
||||
|
||||
ixl_flush(hw);
|
||||
/* Mark outstanding work */
|
||||
if (que->busy == 0)
|
||||
que->busy = 1;
|
||||
|
@ -810,7 +810,7 @@ nvme_ctrlr_intx_handler(void *arg)
|
||||
|
||||
nvme_qpair_process_completions(&ctrlr->adminq);
|
||||
|
||||
if (ctrlr->ioq[0].cpl)
|
||||
if (ctrlr->ioq && ctrlr->ioq[0].cpl)
|
||||
nvme_qpair_process_completions(&ctrlr->ioq[0]);
|
||||
|
||||
nvme_mmio_write_4(ctrlr, intmc, 1);
|
||||
|
@ -2358,6 +2358,8 @@ xhci_configure_endpoint(struct usb_device *udev,
|
||||
|
||||
/* store endpoint mode */
|
||||
pepext->trb_ep_mode = ep_mode;
|
||||
/* store bMaxPacketSize for control endpoints */
|
||||
pepext->trb_ep_maxp = edesc->wMaxPacketSize[0];
|
||||
usb_pc_cpu_flush(pepext->page_cache);
|
||||
|
||||
if (ep_mode == USB_EP_MODE_STREAMS) {
|
||||
@ -2904,6 +2906,17 @@ xhci_transfer_insert(struct usb_xfer *xfer)
|
||||
return (USB_ERR_NOMEM);
|
||||
}
|
||||
|
||||
/* check if bMaxPacketSize changed */
|
||||
if (xfer->flags_int.control_xfr != 0 &&
|
||||
pepext->trb_ep_maxp != xfer->endpoint->edesc->wMaxPacketSize[0]) {
|
||||
|
||||
DPRINTFN(8, "Reconfigure control endpoint\n");
|
||||
|
||||
/* force driver to reconfigure endpoint */
|
||||
pepext->trb_halted = 1;
|
||||
pepext->trb_running = 0;
|
||||
}
|
||||
|
||||
/* check for stopped condition, after putting transfer on interrupt queue */
|
||||
if (pepext->trb_running == 0) {
|
||||
struct xhci_softc *sc = XHCI_BUS2SC(xfer->xroot->bus);
|
||||
|
@ -383,6 +383,7 @@ struct xhci_endpoint_ext {
|
||||
uint8_t trb_halted;
|
||||
uint8_t trb_running;
|
||||
uint8_t trb_ep_mode;
|
||||
uint8_t trb_ep_maxp;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -1,684 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2010-2012 Aleksandr Rybalko
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* GEOM UNCOMPRESS module - simple decompression module for use with read-only
|
||||
* copressed images maked by mkuzip(8) or mkulzma(8) utilities.
|
||||
*
|
||||
* To enable module in kernel config, put this line:
|
||||
* device geom_uncompress
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/zlib.h>
|
||||
|
||||
#include <geom/geom.h>
|
||||
|
||||
#include <contrib/xz-embedded/linux/include/linux/xz.h>
|
||||
|
||||
#ifdef GEOM_UNCOMPRESS_DEBUG
|
||||
#define DPRINTF(a) printf a
|
||||
extern int g_debugflags;
|
||||
#else
|
||||
#define DPRINTF(a)
|
||||
#endif
|
||||
|
||||
static MALLOC_DEFINE(M_GEOM_UNCOMPRESS, "geom_uncompress",
|
||||
"GEOM UNCOMPRESS data structures");
|
||||
|
||||
#define UNCOMPRESS_CLASS_NAME "UNCOMPRESS"
|
||||
#define GEOM_UZIP_MAJVER '2'
|
||||
#define GEOM_ULZMA_MAJVER '3'
|
||||
|
||||
/*
|
||||
* Maximum allowed valid block size (to prevent foot-shooting)
|
||||
*/
|
||||
#define MAX_BLKSZ (MAXPHYS)
|
||||
|
||||
/*
|
||||
* Integer values (block size, number of blocks, offsets)
|
||||
* are stored in big-endian (network) order on disk and struct cloop_header
|
||||
* and in native order in struct g_uncompress_softc
|
||||
*/
|
||||
|
||||
#define CLOOP_MAGIC_LEN 128
|
||||
static char CLOOP_MAGIC_START[] = "#!/bin/sh\n";
|
||||
|
||||
struct cloop_header {
|
||||
char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
};
|
||||
|
||||
struct g_uncompress_softc {
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
uint64_t *offsets;
|
||||
enum {
|
||||
GEOM_UZIP = 1,
|
||||
GEOM_ULZMA
|
||||
} type;
|
||||
|
||||
struct mtx last_mtx;
|
||||
uint32_t last_blk; /* last blk no */
|
||||
char *last_buf; /* last blk data */
|
||||
int req_total; /* total requests */
|
||||
int req_cached; /* cached requests */
|
||||
|
||||
/* XZ decoder structs */
|
||||
struct xz_buf *b;
|
||||
struct xz_dec *s;
|
||||
z_stream *zs;
|
||||
};
|
||||
|
||||
static void
|
||||
g_uncompress_softc_free(struct g_uncompress_softc *sc, struct g_geom *gp)
|
||||
{
|
||||
|
||||
if (gp != NULL) {
|
||||
DPRINTF(("%s: %d requests, %d cached\n",
|
||||
gp->name, sc->req_total, sc->req_cached));
|
||||
}
|
||||
if (sc->offsets != NULL) {
|
||||
free(sc->offsets, M_GEOM_UNCOMPRESS);
|
||||
sc->offsets = NULL;
|
||||
}
|
||||
|
||||
switch (sc->type) {
|
||||
case GEOM_ULZMA:
|
||||
if (sc->b) {
|
||||
free(sc->b, M_GEOM_UNCOMPRESS);
|
||||
sc->b = 0;
|
||||
}
|
||||
if (sc->s) {
|
||||
xz_dec_end(sc->s);
|
||||
sc->s = 0;
|
||||
}
|
||||
break;
|
||||
case GEOM_UZIP:
|
||||
if (sc->zs) {
|
||||
inflateEnd(sc->zs);
|
||||
free(sc->zs, M_GEOM_UNCOMPRESS);
|
||||
sc->zs = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
mtx_destroy(&sc->last_mtx);
|
||||
free(sc->last_buf, M_GEOM_UNCOMPRESS);
|
||||
free(sc, M_GEOM_UNCOMPRESS);
|
||||
}
|
||||
|
||||
static void *
|
||||
z_alloc(void *nil, u_int type, u_int size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
z_free(void *nil, void *ptr)
|
||||
{
|
||||
|
||||
free(ptr, M_GEOM_UNCOMPRESS);
|
||||
}
|
||||
|
||||
static void
|
||||
g_uncompress_done(struct bio *bp)
|
||||
{
|
||||
struct g_uncompress_softc *sc;
|
||||
struct g_provider *pp, *pp2;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
struct bio *bp2;
|
||||
uint32_t start_blk, i;
|
||||
off_t iolen, pos, upos;
|
||||
size_t bsize;
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
bp2 = bp->bio_parent;
|
||||
pp = bp2->bio_to;
|
||||
gp = pp->geom;
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
pp2 = cp->provider;
|
||||
sc = gp->softc;
|
||||
DPRINTF(("%s: done\n", gp->name));
|
||||
|
||||
bp2->bio_error = bp->bio_error;
|
||||
if (bp2->bio_error != 0)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Example:
|
||||
* Uncompressed block size = 65536
|
||||
* User request: 65540-261632
|
||||
* (4 uncompressed blocks -4B at start, -512B at end)
|
||||
*
|
||||
* We have 512(secsize)*63(nsec) = 32256B at offset 1024
|
||||
* From: 1024 bp->bio_offset = 1024
|
||||
* To: 33280 bp->bio_length = 33280 - 1024 = 32256
|
||||
* Compressed blocks: 0-1020, 1020-1080, 1080-4845, 4845-12444,
|
||||
* 12444-33210, 33210-44100, ...
|
||||
*
|
||||
* Get start_blk from user request:
|
||||
* start_blk = bp2->bio_offset / 65536 = 65540/65536 = 1
|
||||
* bsize (block size of parent) = pp2->sectorsize (Now is 4B)
|
||||
* pos(in stream from parent) = sc->offsets[start_blk] % bsize =
|
||||
* = sc->offsets[1] % 4 = 1020 % 4 = 0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Uncompress data.
|
||||
*/
|
||||
start_blk = bp2->bio_offset / sc->blksz;
|
||||
bsize = pp2->sectorsize;
|
||||
iolen = bp->bio_completed;
|
||||
pos = sc->offsets[start_blk] % bsize;
|
||||
upos = 0;
|
||||
|
||||
DPRINTF(("%s: done: bio_length %jd bio_completed %jd start_blk %d, "
|
||||
"pos %jd, upos %jd (%jd, %d, %zu)\n",
|
||||
gp->name, (intmax_t)bp->bio_length, (intmax_t)bp->bio_completed,
|
||||
start_blk, (intmax_t)pos, (intmax_t)upos,
|
||||
(intmax_t)bp2->bio_offset, sc->blksz, bsize));
|
||||
|
||||
for (i = start_blk; upos < bp2->bio_length; i++) {
|
||||
off_t len, ulen, uoff;
|
||||
|
||||
uoff = i == start_blk ? bp2->bio_offset % sc->blksz : 0;
|
||||
ulen = MIN(sc->blksz - uoff, bp2->bio_length - upos);
|
||||
len = sc->offsets[i + 1] - sc->offsets[i];
|
||||
|
||||
DPRINTF((
|
||||
"%s: done: inflate block %d, start %ju, end %ju len %jd\n",
|
||||
gp->name, i, (uintmax_t)sc->offsets[i],
|
||||
(uintmax_t)sc->offsets[i + 1], (intmax_t)len));
|
||||
|
||||
if (len == 0) {
|
||||
/* All zero block: no cache update */
|
||||
bzero(bp2->bio_data + upos, ulen);
|
||||
upos += ulen;
|
||||
bp2->bio_completed += ulen;
|
||||
continue;
|
||||
}
|
||||
if (len > iolen) {
|
||||
DPRINTF(("%s: done: early termination: len (%jd) > "
|
||||
"iolen (%jd)\n",
|
||||
gp->name, (intmax_t)len, (intmax_t)iolen));
|
||||
break;
|
||||
}
|
||||
mtx_lock(&sc->last_mtx);
|
||||
|
||||
#ifdef GEOM_UNCOMPRESS_DEBUG
|
||||
if (g_debugflags & 32)
|
||||
hexdump(bp->bio_data + pos, len, 0, 0);
|
||||
#endif
|
||||
|
||||
switch (sc->type) {
|
||||
case GEOM_ULZMA:
|
||||
sc->b->in = bp->bio_data + pos;
|
||||
sc->b->out = sc->last_buf;
|
||||
sc->b->in_pos = sc->b->out_pos = 0;
|
||||
sc->b->in_size = len;
|
||||
sc->b->out_size = (size_t)-1;
|
||||
|
||||
err = (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END) ?
|
||||
1 : 0;
|
||||
/* TODO decoder recovery, if needed */
|
||||
break;
|
||||
case GEOM_UZIP:
|
||||
sc->zs->next_in = bp->bio_data + pos;
|
||||
sc->zs->avail_in = len;
|
||||
sc->zs->next_out = sc->last_buf;
|
||||
sc->zs->avail_out = sc->blksz;
|
||||
|
||||
err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ?
|
||||
1 : 0;
|
||||
if ((err) || (inflateReset(sc->zs) != Z_OK))
|
||||
printf("%s: UZIP decoder reset failed\n",
|
||||
gp->name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
sc->last_blk = -1;
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
DPRINTF(("%s: done: inflate failed, code=%d\n",
|
||||
gp->name, err));
|
||||
bp2->bio_error = EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef GEOM_UNCOMPRESS_DEBUG
|
||||
if (g_debugflags & 32)
|
||||
hexdump(sc->last_buf, sc->b->out_size, 0, 0);
|
||||
#endif
|
||||
|
||||
sc->last_blk = i;
|
||||
DPRINTF(("%s: done: inflated \n", gp->name));
|
||||
memcpy(bp2->bio_data + upos, sc->last_buf + uoff, ulen);
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
|
||||
pos += len;
|
||||
iolen -= len;
|
||||
upos += ulen;
|
||||
bp2->bio_completed += ulen;
|
||||
}
|
||||
|
||||
done:
|
||||
/*
|
||||
* Finish processing the request.
|
||||
*/
|
||||
DPRINTF(("%s: done: (%d, %jd, %ld)\n",
|
||||
gp->name, bp2->bio_error, (intmax_t)bp2->bio_completed,
|
||||
bp2->bio_resid));
|
||||
free(bp->bio_data, M_GEOM_UNCOMPRESS);
|
||||
g_destroy_bio(bp);
|
||||
g_io_deliver(bp2, bp2->bio_error);
|
||||
}
|
||||
|
||||
static void
|
||||
g_uncompress_start(struct bio *bp)
|
||||
{
|
||||
struct g_uncompress_softc *sc;
|
||||
struct g_provider *pp, *pp2;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
struct bio *bp2;
|
||||
uint32_t start_blk, end_blk;
|
||||
size_t bsize;
|
||||
|
||||
pp = bp->bio_to;
|
||||
gp = pp->geom;
|
||||
DPRINTF(("%s: start (%d:%s) to %s off=%jd len=%jd\n",
|
||||
gp->name, bp->bio_cmd,
|
||||
(bp->bio_cmd == BIO_READ) ? "BIO_READ" : "NOTSUPPORTED",
|
||||
pp->name, (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length));
|
||||
|
||||
if (bp->bio_cmd != BIO_READ) {
|
||||
g_io_deliver(bp, EOPNOTSUPP);
|
||||
return;
|
||||
}
|
||||
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
pp2 = cp->provider;
|
||||
sc = gp->softc;
|
||||
|
||||
start_blk = bp->bio_offset / sc->blksz;
|
||||
end_blk = howmany(bp->bio_offset + bp->bio_length, sc->blksz);
|
||||
KASSERT(start_blk < sc->nblocks, ("start_blk out of range"));
|
||||
KASSERT(end_blk <= sc->nblocks, ("end_blk out of range"));
|
||||
|
||||
sc->req_total++;
|
||||
if (start_blk + 1 == end_blk) {
|
||||
mtx_lock(&sc->last_mtx);
|
||||
if (start_blk == sc->last_blk) {
|
||||
off_t uoff;
|
||||
|
||||
uoff = bp->bio_offset % sc->blksz;
|
||||
KASSERT(bp->bio_length <= sc->blksz - uoff,
|
||||
("cached data error"));
|
||||
memcpy(bp->bio_data, sc->last_buf + uoff,
|
||||
bp->bio_length);
|
||||
sc->req_cached++;
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
|
||||
DPRINTF(("%s: start: cached 0 + %jd, %jd + 0 + %jd\n",
|
||||
gp->name, (intmax_t)bp->bio_length, (intmax_t)uoff,
|
||||
(intmax_t)bp->bio_length));
|
||||
bp->bio_completed = bp->bio_length;
|
||||
g_io_deliver(bp, 0);
|
||||
return;
|
||||
}
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
}
|
||||
|
||||
bp2 = g_clone_bio(bp);
|
||||
if (bp2 == NULL) {
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
return;
|
||||
}
|
||||
DPRINTF(("%s: start (%d..%d), %s: %d + %jd, %s: %d + %jd\n",
|
||||
gp->name, start_blk, end_blk,
|
||||
pp->name, pp->sectorsize, (intmax_t)pp->mediasize,
|
||||
pp2->name, pp2->sectorsize, (intmax_t)pp2->mediasize));
|
||||
bsize = pp2->sectorsize;
|
||||
bp2->bio_done = g_uncompress_done;
|
||||
bp2->bio_offset = rounddown(sc->offsets[start_blk], bsize);
|
||||
while (1) {
|
||||
bp2->bio_length = roundup(sc->offsets[end_blk], bsize) -
|
||||
bp2->bio_offset;
|
||||
if (bp2->bio_length < MAXPHYS)
|
||||
break;
|
||||
|
||||
end_blk--;
|
||||
DPRINTF((
|
||||
"%s: bio_length (%jd) > MAXPHYS: lowering end_blk to %u\n",
|
||||
gp->name, (intmax_t)bp2->bio_length, end_blk));
|
||||
}
|
||||
DPRINTF(("%s: start %jd + %jd -> %ju + %ju -> %jd + %jd\n",
|
||||
gp->name,
|
||||
(intmax_t)bp->bio_offset, (intmax_t)bp->bio_length,
|
||||
(uintmax_t)sc->offsets[start_blk],
|
||||
(uintmax_t)sc->offsets[end_blk] - sc->offsets[start_blk],
|
||||
(intmax_t)bp2->bio_offset, (intmax_t)bp2->bio_length));
|
||||
bp2->bio_data = malloc(bp2->bio_length, M_GEOM_UNCOMPRESS, M_NOWAIT);
|
||||
if (bp2->bio_data == NULL) {
|
||||
g_destroy_bio(bp2);
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
g_io_request(bp2, cp);
|
||||
DPRINTF(("%s: start ok\n", gp->name));
|
||||
}
|
||||
|
||||
static void
|
||||
g_uncompress_orphan(struct g_consumer *cp)
|
||||
{
|
||||
struct g_geom *gp;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->provider->name);
|
||||
g_topology_assert();
|
||||
|
||||
gp = cp->geom;
|
||||
g_uncompress_softc_free(gp->softc, gp);
|
||||
gp->softc = NULL;
|
||||
g_wither_geom(gp, ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uncompress_access(struct g_provider *pp, int dr, int dw, int de)
|
||||
{
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
|
||||
gp = pp->geom;
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
KASSERT (cp != NULL, ("g_uncompress_access but no consumer"));
|
||||
|
||||
if (cp->acw + dw > 0)
|
||||
return (EROFS);
|
||||
|
||||
return (g_access(cp, dr, dw, de));
|
||||
}
|
||||
|
||||
static void
|
||||
g_uncompress_spoiled(struct g_consumer *cp)
|
||||
{
|
||||
struct g_geom *gp;
|
||||
|
||||
gp = cp->geom;
|
||||
g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, gp->name);
|
||||
g_topology_assert();
|
||||
|
||||
g_uncompress_softc_free(gp->softc, gp);
|
||||
gp->softc = NULL;
|
||||
g_wither_geom(gp, ENXIO);
|
||||
}
|
||||
|
||||
static struct g_geom *
|
||||
g_uncompress_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
{
|
||||
struct cloop_header *header;
|
||||
struct g_uncompress_softc *sc;
|
||||
struct g_provider *pp2;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
uint64_t *offsets;
|
||||
uint32_t i, r, total, total_offsets, type;
|
||||
uint8_t *buf;
|
||||
int error;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, pp->name);
|
||||
g_topology_assert();
|
||||
|
||||
/* Skip providers that are already open for writing. */
|
||||
if (pp->acw > 0)
|
||||
return (NULL);
|
||||
|
||||
buf = NULL;
|
||||
|
||||
/*
|
||||
* Create geom instance.
|
||||
*/
|
||||
gp = g_new_geomf(mp, "%s.uncompress", pp->name);
|
||||
cp = g_new_consumer(gp);
|
||||
error = g_attach(cp, pp);
|
||||
if (error == 0)
|
||||
error = g_access(cp, 1, 0, 0);
|
||||
if (error) {
|
||||
g_detach(cp);
|
||||
g_destroy_consumer(cp);
|
||||
g_destroy_geom(gp);
|
||||
return (NULL);
|
||||
}
|
||||
g_topology_unlock();
|
||||
|
||||
/*
|
||||
* Read cloop header, look for CLOOP magic, perform
|
||||
* other validity checks.
|
||||
*/
|
||||
DPRINTF(("%s: media sectorsize %u, mediasize %jd\n",
|
||||
gp->name, pp->sectorsize, (intmax_t)pp->mediasize));
|
||||
total = roundup(sizeof(struct cloop_header), pp->sectorsize);
|
||||
buf = g_read_data(cp, 0, total, NULL);
|
||||
if (buf == NULL)
|
||||
goto err;
|
||||
header = (struct cloop_header *) buf;
|
||||
if (strncmp(header->magic, CLOOP_MAGIC_START,
|
||||
sizeof(CLOOP_MAGIC_START) - 1) != 0) {
|
||||
DPRINTF(("%s: no CLOOP magic\n", gp->name));
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (header->magic[0x0b]) {
|
||||
case 'L':
|
||||
type = GEOM_ULZMA;
|
||||
if (header->magic[0x0c] < GEOM_ULZMA_MAJVER) {
|
||||
DPRINTF(("%s: image version too old\n", gp->name));
|
||||
goto err;
|
||||
}
|
||||
DPRINTF(("%s: GEOM_ULZMA image found\n", gp->name));
|
||||
break;
|
||||
case 'V':
|
||||
type = GEOM_UZIP;
|
||||
if (header->magic[0x0c] < GEOM_UZIP_MAJVER) {
|
||||
DPRINTF(("%s: image version too old\n", gp->name));
|
||||
goto err;
|
||||
}
|
||||
DPRINTF(("%s: GEOM_UZIP image found\n", gp->name));
|
||||
break;
|
||||
default:
|
||||
DPRINTF(("%s: unsupported image type\n", gp->name));
|
||||
goto err;
|
||||
}
|
||||
|
||||
DPRINTF(("%s: found CLOOP magic\n", gp->name));
|
||||
/*
|
||||
* Initialize softc and read offsets.
|
||||
*/
|
||||
sc = malloc(sizeof(*sc), M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
|
||||
gp->softc = sc;
|
||||
sc->type = type;
|
||||
sc->blksz = ntohl(header->blksz);
|
||||
sc->nblocks = ntohl(header->nblocks);
|
||||
if (sc->blksz % 4 != 0) {
|
||||
printf("%s: block size (%u) should be multiple of 4.\n",
|
||||
gp->name, sc->blksz);
|
||||
goto err;
|
||||
}
|
||||
if (sc->blksz > MAX_BLKSZ) {
|
||||
printf("%s: block size (%u) should not be larger than %d.\n",
|
||||
gp->name, sc->blksz, MAX_BLKSZ);
|
||||
}
|
||||
total_offsets = sc->nblocks + 1;
|
||||
if (sizeof(struct cloop_header) +
|
||||
total_offsets * sizeof(uint64_t) > pp->mediasize) {
|
||||
printf("%s: media too small for %u blocks\n",
|
||||
gp->name, sc->nblocks);
|
||||
goto err;
|
||||
}
|
||||
g_free(buf);
|
||||
|
||||
sc->offsets = malloc(total_offsets * sizeof(uint64_t),
|
||||
M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
|
||||
total = roundup((sizeof(struct cloop_header) +
|
||||
total_offsets * sizeof(uint64_t)), pp->sectorsize);
|
||||
#define RSZ ((total - r) > MAXPHYS ? MAXPHYS: (total - r))
|
||||
for (r = 0, i = 0; r < total; r += MAXPHYS) {
|
||||
buf = g_read_data(cp, r, RSZ, &error);
|
||||
if (buf == NULL) {
|
||||
free(sc->offsets, M_GEOM_UNCOMPRESS);
|
||||
goto err;
|
||||
}
|
||||
offsets = (uint64_t *)buf;
|
||||
if (r == 0)
|
||||
offsets +=
|
||||
sizeof(struct cloop_header) / sizeof(uint64_t);
|
||||
for (; i < total_offsets && offsets < (uint64_t *)(buf + RSZ);
|
||||
i++, offsets++)
|
||||
sc->offsets[i] = be64toh(*offsets);
|
||||
g_free(buf);
|
||||
}
|
||||
#undef RSZ
|
||||
buf = NULL;
|
||||
DPRINTF(("%s: done reading offsets\n", gp->name));
|
||||
mtx_init(&sc->last_mtx, "geom_uncompress cache", NULL, MTX_DEF);
|
||||
sc->last_blk = -1;
|
||||
sc->last_buf = malloc(sc->blksz, M_GEOM_UNCOMPRESS, M_WAITOK);
|
||||
sc->req_total = 0;
|
||||
sc->req_cached = 0;
|
||||
|
||||
switch (sc->type) {
|
||||
case GEOM_ULZMA:
|
||||
xz_crc32_init();
|
||||
sc->s = xz_dec_init(XZ_SINGLE, 0);
|
||||
sc->b = (struct xz_buf*)malloc(sizeof(struct xz_buf),
|
||||
M_GEOM_UNCOMPRESS, M_WAITOK);
|
||||
break;
|
||||
case GEOM_UZIP:
|
||||
sc->zs = (z_stream *)malloc(sizeof(z_stream),
|
||||
M_GEOM_UNCOMPRESS, M_WAITOK);
|
||||
sc->zs->zalloc = z_alloc;
|
||||
sc->zs->zfree = z_free;
|
||||
if (inflateInit(sc->zs) != Z_OK) {
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
g_topology_lock();
|
||||
pp2 = g_new_providerf(gp, "%s", gp->name);
|
||||
pp2->sectorsize = 512;
|
||||
pp2->mediasize = (off_t)sc->nblocks * sc->blksz;
|
||||
if (pp->stripesize > 0) {
|
||||
pp2->stripesize = pp->stripesize;
|
||||
pp2->stripeoffset = pp->stripeoffset;
|
||||
}
|
||||
g_error_provider(pp2, 0);
|
||||
g_access(cp, -1, 0, 0);
|
||||
|
||||
DPRINTF(("%s: taste ok (%d, %jd), (%d, %d), %x\n",
|
||||
gp->name,
|
||||
pp2->sectorsize, (intmax_t)pp2->mediasize,
|
||||
pp2->stripeoffset, pp2->stripesize, pp2->flags));
|
||||
DPRINTF(("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz));
|
||||
return (gp);
|
||||
|
||||
err:
|
||||
g_topology_lock();
|
||||
g_access(cp, -1, 0, 0);
|
||||
if (buf != NULL)
|
||||
g_free(buf);
|
||||
if (gp->softc != NULL) {
|
||||
g_uncompress_softc_free(gp->softc, NULL);
|
||||
gp->softc = NULL;
|
||||
}
|
||||
g_detach(cp);
|
||||
g_destroy_consumer(cp);
|
||||
g_destroy_geom(gp);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uncompress_destroy_geom(struct gctl_req *req, struct g_class *mp,
|
||||
struct g_geom *gp)
|
||||
{
|
||||
struct g_provider *pp;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, gp->name);
|
||||
g_topology_assert();
|
||||
|
||||
if (gp->softc == NULL) {
|
||||
DPRINTF(("%s(%s): gp->softc == NULL\n", __func__, gp->name));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
KASSERT(gp != NULL, ("NULL geom"));
|
||||
pp = LIST_FIRST(&gp->provider);
|
||||
KASSERT(pp != NULL, ("NULL provider"));
|
||||
if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)
|
||||
return (EBUSY);
|
||||
|
||||
g_uncompress_softc_free(gp->softc, gp);
|
||||
gp->softc = NULL;
|
||||
g_wither_geom(gp, ENXIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct g_class g_uncompress_class = {
|
||||
.name = UNCOMPRESS_CLASS_NAME,
|
||||
.version = G_VERSION,
|
||||
.taste = g_uncompress_taste,
|
||||
.destroy_geom = g_uncompress_destroy_geom,
|
||||
|
||||
.start = g_uncompress_start,
|
||||
.orphan = g_uncompress_orphan,
|
||||
.access = g_uncompress_access,
|
||||
.spoiled = g_uncompress_spoiled,
|
||||
};
|
||||
|
||||
DECLARE_GEOM_CLASS(g_uncompress_class, g_uncompress);
|
||||
MODULE_DEPEND(g_uncompress, zlib, 1, 1, 1);
|
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* Copyright (c) 2014 Juniper Networks, Inc.
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -38,91 +39,116 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/zlib.h>
|
||||
#include <sys/kthread.h>
|
||||
|
||||
#include <geom/geom.h>
|
||||
|
||||
FEATURE(geom_uzip, "GEOM uzip read-only compressed disks support");
|
||||
#include <geom/uzip/g_uzip.h>
|
||||
#include <geom/uzip/g_uzip_cloop.h>
|
||||
#include <geom/uzip/g_uzip_softc.h>
|
||||
#include <geom/uzip/g_uzip_dapi.h>
|
||||
#include <geom/uzip/g_uzip_zlib.h>
|
||||
#include <geom/uzip/g_uzip_lzma.h>
|
||||
#include <geom/uzip/g_uzip_wrkthr.h>
|
||||
|
||||
#undef GEOM_UZIP_DEBUG
|
||||
#ifdef GEOM_UZIP_DEBUG
|
||||
#define DPRINTF(a) printf a
|
||||
#else
|
||||
#define DPRINTF(a)
|
||||
MALLOC_DEFINE(M_GEOM_UZIP, "geom_uzip", "GEOM UZIP data structures");
|
||||
|
||||
FEATURE(geom_uzip, "GEOM read-only compressed disks support");
|
||||
|
||||
struct g_uzip_blk {
|
||||
uint64_t offset;
|
||||
uint32_t blen;
|
||||
#define BLEN_UNDEF UINT32_MAX
|
||||
};
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(a) ((a) < 0 ? -(a) : (a))
|
||||
#endif
|
||||
|
||||
static MALLOC_DEFINE(M_GEOM_UZIP, "geom_uzip", "GEOM UZIP data structures");
|
||||
#define BLK_IN_RANGE(mcn, bcn, ilen) \
|
||||
(((bcn) != BLEN_UNDEF) && ( \
|
||||
((ilen) >= 0 && (mcn >= bcn) && (mcn <= ((intmax_t)(bcn) + (ilen)))) || \
|
||||
((ilen) < 0 && (mcn <= bcn) && (mcn >= ((intmax_t)(bcn) + (ilen)))) \
|
||||
))
|
||||
|
||||
#ifdef GEOM_UZIP_DEBUG
|
||||
# define GEOM_UZIP_DBG_DEFAULT 3
|
||||
#else
|
||||
# define GEOM_UZIP_DBG_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#define GUZ_DBG_ERR 1
|
||||
#define GUZ_DBG_INFO 2
|
||||
#define GUZ_DBG_IO 3
|
||||
#define GUZ_DBG_TOC 4
|
||||
|
||||
SYSCTL_DECL(_kern_geom);
|
||||
SYSCTL_NODE(_kern_geom, OID_AUTO, uzip, CTLFLAG_RW, 0, "GEOM_UZIP stuff");
|
||||
static u_int g_uzip_debug = GEOM_UZIP_DBG_DEFAULT;
|
||||
SYSCTL_UINT(_kern_geom_uzip, OID_AUTO, debug, CTLFLAG_RWTUN, &g_uzip_debug, 0,
|
||||
"Debug level (0-4)");
|
||||
static u_int g_uzip_debug_block = BLEN_UNDEF;
|
||||
SYSCTL_UINT(_kern_geom_uzip, OID_AUTO, debug_block, CTLFLAG_RWTUN,
|
||||
&g_uzip_debug_block, 0, "Debug operations around specific cluster#");
|
||||
|
||||
#define DPRINTF(lvl, a) \
|
||||
if ((lvl) <= g_uzip_debug) { \
|
||||
printf a; \
|
||||
}
|
||||
#define DPRINTF_BLK(lvl, cn, a) \
|
||||
if ((lvl) <= g_uzip_debug || \
|
||||
BLK_IN_RANGE(cn, g_uzip_debug_block, 8) || \
|
||||
BLK_IN_RANGE(cn, g_uzip_debug_block, -8)) { \
|
||||
printf a; \
|
||||
}
|
||||
#define DPRINTF_BRNG(lvl, bcn, ecn, a) \
|
||||
if (bcn >= ecn) { \
|
||||
printf("DPRINTF_BRNG: invalid range (%ju, %ju), BUG BUG " \
|
||||
"BUG!\n", (uintmax_t)bcn, (uintmax_t)ecn); \
|
||||
} else if (((lvl) <= g_uzip_debug) || \
|
||||
BLK_IN_RANGE(g_uzip_debug_block, bcn, \
|
||||
(intmax_t)ecn - (intmax_t)bcn)) { \
|
||||
printf a; \
|
||||
}
|
||||
|
||||
#define UZIP_CLASS_NAME "UZIP"
|
||||
|
||||
/*
|
||||
* Maximum allowed valid block size (to prevent foot-shooting)
|
||||
*/
|
||||
#define MAX_BLKSZ (MAXPHYS - MAXPHYS / 1000 - 12)
|
||||
#define MAX_BLKSZ (MAXPHYS)
|
||||
|
||||
/*
|
||||
* Integer values (block size, number of blocks, offsets)
|
||||
* are stored in big-endian (network) order on disk and struct cloop_header
|
||||
* and in native order in struct g_uzip_softc
|
||||
*/
|
||||
|
||||
#define CLOOP_MAGIC_LEN 128
|
||||
static char CLOOP_MAGIC_START[] = "#!/bin/sh\n";
|
||||
|
||||
struct cloop_header {
|
||||
char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
};
|
||||
|
||||
struct g_uzip_softc {
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
uint64_t *offsets;
|
||||
|
||||
struct mtx last_mtx;
|
||||
uint32_t last_blk; /* last blk no */
|
||||
char *last_buf; /* last blk data */
|
||||
int req_total; /* total requests */
|
||||
int req_cached; /* cached requests */
|
||||
};
|
||||
|
||||
static void g_uzip_done(struct bio *bp);
|
||||
static void g_uzip_read_done(struct bio *bp);
|
||||
static void g_uzip_do(struct g_uzip_softc *, struct bio *bp);
|
||||
|
||||
static void
|
||||
g_uzip_softc_free(struct g_uzip_softc *sc, struct g_geom *gp)
|
||||
{
|
||||
|
||||
if (gp != NULL) {
|
||||
DPRINTF(("%s: %d requests, %d cached\n",
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: %d requests, %d cached\n",
|
||||
gp->name, sc->req_total, sc->req_cached));
|
||||
}
|
||||
if (sc->offsets != NULL) {
|
||||
free(sc->offsets, M_GEOM_UZIP);
|
||||
sc->offsets = NULL;
|
||||
|
||||
mtx_lock(&sc->queue_mtx);
|
||||
sc->wrkthr_flags |= GUZ_SHUTDOWN;
|
||||
wakeup(sc);
|
||||
while (!(sc->wrkthr_flags & GUZ_EXITING)) {
|
||||
msleep(sc->procp, &sc->queue_mtx, PRIBIO, "guzfree",
|
||||
hz / 10);
|
||||
}
|
||||
mtx_unlock(&sc->queue_mtx);
|
||||
|
||||
sc->dcp->free(sc->dcp);
|
||||
free(sc->toc, M_GEOM_UZIP);
|
||||
mtx_destroy(&sc->queue_mtx);
|
||||
mtx_destroy(&sc->last_mtx);
|
||||
free(sc->last_buf, M_GEOM_UZIP);
|
||||
free(sc, M_GEOM_UZIP);
|
||||
}
|
||||
|
||||
static void *
|
||||
z_alloc(void *nil, u_int type, u_int size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = malloc(type * size, M_GEOM_UZIP, M_NOWAIT);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
z_free(void *nil, void *ptr)
|
||||
{
|
||||
|
||||
free(ptr, M_GEOM_UZIP);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uzip_cached(struct g_geom *gp, struct bio *bp)
|
||||
{
|
||||
@ -144,8 +170,9 @@ g_uzip_cached(struct g_geom *gp, struct bio *bp)
|
||||
sc->req_cached++;
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
|
||||
DPRINTF(("%s/%s: %p: offset=%jd: got %jd bytes from cache\n",
|
||||
__func__, gp->name, bp, (intmax_t)ofs, (intmax_t)usz));
|
||||
DPRINTF(GUZ_DBG_IO, ("%s/%s: %p: offset=%jd: got %jd bytes "
|
||||
"from cache\n", __func__, gp->name, bp, (intmax_t)ofs,
|
||||
(intmax_t)usz));
|
||||
|
||||
bp->bio_completed += usz;
|
||||
bp->bio_resid -= usz;
|
||||
@ -160,6 +187,19 @@ g_uzip_cached(struct g_geom *gp, struct bio *bp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define BLK_ENDS(sc, bi) ((sc)->toc[(bi)].offset + \
|
||||
(sc)->toc[(bi)].blen)
|
||||
|
||||
#define BLK_IS_CONT(sc, bi) (BLK_ENDS((sc), (bi) - 1) == \
|
||||
(sc)->toc[(bi)].offset)
|
||||
#define BLK_IS_NIL(sc, bi) ((sc)->toc[(bi)].blen == 0)
|
||||
|
||||
#define TOFF_2_BOFF(sc, pp, bi) ((sc)->toc[(bi)].offset - \
|
||||
(sc)->toc[(bi)].offset % (pp)->sectorsize)
|
||||
#define TLEN_2_BLEN(sc, pp, bp, ei) ((BLK_ENDS((sc), (ei)) - \
|
||||
(bp)->bio_offset + (pp)->sectorsize - 1) / \
|
||||
(pp)->sectorsize * (pp)->sectorsize)
|
||||
|
||||
static int
|
||||
g_uzip_request(struct g_geom *gp, struct bio *bp)
|
||||
{
|
||||
@ -167,21 +207,14 @@ g_uzip_request(struct g_geom *gp, struct bio *bp)
|
||||
struct bio *bp2;
|
||||
struct g_consumer *cp;
|
||||
struct g_provider *pp;
|
||||
off_t ofs;
|
||||
size_t start_blk, end_blk;
|
||||
off_t ofs, start_blk_ofs;
|
||||
size_t i, start_blk, end_blk, zsize;
|
||||
|
||||
if (g_uzip_cached(gp, bp) != 0)
|
||||
return (1);
|
||||
|
||||
sc = gp->softc;
|
||||
|
||||
bp2 = g_clone_bio(bp);
|
||||
if (bp2 == NULL) {
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
return (1);
|
||||
}
|
||||
bp2->bio_done = g_uzip_done;
|
||||
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
pp = cp->provider;
|
||||
|
||||
@ -191,17 +224,54 @@ g_uzip_request(struct g_geom *gp, struct bio *bp)
|
||||
end_blk = (ofs + bp->bio_resid + sc->blksz - 1) / sc->blksz;
|
||||
KASSERT(end_blk <= sc->nblocks, ("end_blk out of range"));
|
||||
|
||||
DPRINTF(("%s/%s: %p: start=%u (%jd), end=%u (%jd)\n",
|
||||
__func__, gp->name, bp,
|
||||
(u_int)start_blk, (intmax_t)sc->offsets[start_blk],
|
||||
(u_int)end_blk, (intmax_t)sc->offsets[end_blk]));
|
||||
for (; BLK_IS_NIL(sc, start_blk) && start_blk < end_blk; start_blk++) {
|
||||
/* Fill in any leading Nil blocks */
|
||||
start_blk_ofs = ofs % sc->blksz;
|
||||
zsize = MIN(sc->blksz - start_blk_ofs, bp->bio_resid);
|
||||
DPRINTF_BLK(GUZ_DBG_IO, start_blk, ("%s/%s: %p/%ju: "
|
||||
"filling %ju zero bytes\n", __func__, gp->name, gp,
|
||||
(uintmax_t)bp->bio_completed, (uintmax_t)zsize));
|
||||
bzero(bp->bio_data + bp->bio_completed, zsize);
|
||||
bp->bio_completed += zsize;
|
||||
bp->bio_resid -= zsize;
|
||||
ofs += zsize;
|
||||
}
|
||||
|
||||
bp2->bio_offset = sc->offsets[start_blk] -
|
||||
sc->offsets[start_blk] % pp->sectorsize;
|
||||
if (start_blk == end_blk) {
|
||||
KASSERT(bp->bio_resid == 0, ("bp->bio_resid is invalid"));
|
||||
/*
|
||||
* No non-Nil data is left, complete request immediately.
|
||||
*/
|
||||
DPRINTF(GUZ_DBG_IO, ("%s/%s: %p: all done returning %ju "
|
||||
"bytes\n", __func__, gp->name, gp,
|
||||
(uintmax_t)bp->bio_completed));
|
||||
g_io_deliver(bp, 0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = start_blk + 1; i < end_blk; i++) {
|
||||
/* Trim discontinuous areas if any */
|
||||
if (!BLK_IS_CONT(sc, i)) {
|
||||
end_blk = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTF_BRNG(GUZ_DBG_IO, start_blk, end_blk, ("%s/%s: %p: "
|
||||
"start=%u (%ju), end=%u (%ju)\n", __func__, gp->name, bp,
|
||||
(u_int)start_blk, (uintmax_t)sc->toc[start_blk].offset,
|
||||
(u_int)end_blk, (uintmax_t)BLK_ENDS(sc, end_blk - 1)));
|
||||
|
||||
bp2 = g_clone_bio(bp);
|
||||
if (bp2 == NULL) {
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
return (1);
|
||||
}
|
||||
bp2->bio_done = g_uzip_read_done;
|
||||
|
||||
bp2->bio_offset = TOFF_2_BOFF(sc, pp, start_blk);
|
||||
while (1) {
|
||||
bp2->bio_length = sc->offsets[end_blk] - bp2->bio_offset;
|
||||
bp2->bio_length = (bp2->bio_length + pp->sectorsize - 1) /
|
||||
pp->sectorsize * pp->sectorsize;
|
||||
bp2->bio_length = TLEN_2_BLEN(sc, pp, bp2, end_blk - 1);
|
||||
if (bp2->bio_length <= MAXPHYS)
|
||||
break;
|
||||
|
||||
@ -215,8 +285,8 @@ g_uzip_request(struct g_geom *gp, struct bio *bp)
|
||||
return (1);
|
||||
}
|
||||
|
||||
DPRINTF(("%s/%s: %p: reading %jd bytes from offset %jd\n",
|
||||
__func__, gp->name, bp,
|
||||
DPRINTF_BRNG(GUZ_DBG_IO, start_blk, end_blk, ("%s/%s: %p: "
|
||||
"reading %jd bytes from offset %jd\n", __func__, gp->name, bp,
|
||||
(intmax_t)bp2->bio_length, (intmax_t)bp2->bio_offset));
|
||||
|
||||
g_io_request(bp2, cp);
|
||||
@ -224,22 +294,37 @@ g_uzip_request(struct g_geom *gp, struct bio *bp)
|
||||
}
|
||||
|
||||
static void
|
||||
g_uzip_done(struct bio *bp)
|
||||
g_uzip_read_done(struct bio *bp)
|
||||
{
|
||||
z_stream zs;
|
||||
struct bio *bp2;
|
||||
struct g_provider *pp;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
struct g_uzip_softc *sc;
|
||||
char *data, *data2;
|
||||
off_t ofs;
|
||||
size_t blk, blkofs, len, ulen;
|
||||
|
||||
bp2 = bp->bio_parent;
|
||||
gp = bp2->bio_to->geom;
|
||||
sc = gp->softc;
|
||||
|
||||
mtx_lock(&sc->queue_mtx);
|
||||
bioq_disksort(&sc->bio_queue, bp);
|
||||
mtx_unlock(&sc->queue_mtx);
|
||||
wakeup(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
g_uzip_do(struct g_uzip_softc *sc, struct bio *bp)
|
||||
{
|
||||
struct bio *bp2;
|
||||
struct g_provider *pp;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
char *data, *data2;
|
||||
off_t ofs;
|
||||
size_t blk, blkofs, len, ulen, firstblk;
|
||||
int err;
|
||||
|
||||
bp2 = bp->bio_parent;
|
||||
gp = bp2->bio_to->geom;
|
||||
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
pp = cp->provider;
|
||||
|
||||
@ -253,46 +338,47 @@ g_uzip_done(struct bio *bp)
|
||||
goto done;
|
||||
}
|
||||
|
||||
zs.zalloc = z_alloc;
|
||||
zs.zfree = z_free;
|
||||
if (inflateInit(&zs) != Z_OK) {
|
||||
bp2->bio_error = EILSEQ;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ofs = bp2->bio_offset + bp2->bio_completed;
|
||||
blk = ofs / sc->blksz;
|
||||
firstblk = blk = ofs / sc->blksz;
|
||||
blkofs = ofs % sc->blksz;
|
||||
data = bp->bio_data + sc->offsets[blk] % pp->sectorsize;
|
||||
data = bp->bio_data + sc->toc[blk].offset % pp->sectorsize;
|
||||
data2 = bp2->bio_data + bp2->bio_completed;
|
||||
while (bp->bio_completed && bp2->bio_resid) {
|
||||
if (blk > firstblk && !BLK_IS_CONT(sc, blk)) {
|
||||
DPRINTF_BLK(GUZ_DBG_IO, blk, ("%s/%s: %p: backref'ed "
|
||||
"cluster #%u requested, looping around\n",
|
||||
__func__, gp->name, bp2, (u_int)blk));
|
||||
goto done;
|
||||
}
|
||||
ulen = MIN(sc->blksz - blkofs, bp2->bio_resid);
|
||||
len = sc->offsets[blk + 1] - sc->offsets[blk];
|
||||
DPRINTF(("%s/%s: %p/%ju: data2=%p, ulen=%u, data=%p, len=%u\n",
|
||||
__func__, gp->name, gp, bp->bio_completed,
|
||||
data2, (u_int)ulen, data, (u_int)len));
|
||||
len = sc->toc[blk].blen;
|
||||
DPRINTF(GUZ_DBG_IO, ("%s/%s: %p/%ju: data2=%p, ulen=%u, "
|
||||
"data=%p, len=%u\n", __func__, gp->name, gp,
|
||||
bp->bio_completed, data2, (u_int)ulen, data, (u_int)len));
|
||||
if (len == 0) {
|
||||
/* All zero block: no cache update */
|
||||
bzero(data2, ulen);
|
||||
} else if (len <= bp->bio_completed) {
|
||||
zs.next_in = data;
|
||||
zs.avail_in = len;
|
||||
zs.next_out = sc->last_buf;
|
||||
zs.avail_out = sc->blksz;
|
||||
mtx_lock(&sc->last_mtx);
|
||||
if (inflate(&zs, Z_FINISH) != Z_STREAM_END) {
|
||||
err = sc->dcp->decompress(sc->dcp, gp->name, data,
|
||||
len, sc->last_buf);
|
||||
if (err != 0) {
|
||||
sc->last_blk = -1;
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
inflateEnd(&zs);
|
||||
bp2->bio_error = EILSEQ;
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s/%s: decompress"
|
||||
"(%p) failed\n", __func__, gp->name,
|
||||
sc->dcp));
|
||||
goto done;
|
||||
}
|
||||
sc->last_blk = blk;
|
||||
memcpy(data2, sc->last_buf + blkofs, ulen);
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
if (inflateReset(&zs) != Z_OK) {
|
||||
inflateEnd(&zs);
|
||||
err = sc->dcp->rewind(sc->dcp, gp->name);
|
||||
if (err != 0) {
|
||||
bp2->bio_error = EILSEQ;
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s/%s: rewind(%p) "
|
||||
"failed\n", __func__, gp->name, sc->dcp));
|
||||
goto done;
|
||||
}
|
||||
data += len;
|
||||
@ -307,9 +393,6 @@ g_uzip_done(struct bio *bp)
|
||||
blk++;
|
||||
}
|
||||
|
||||
if (inflateEnd(&zs) != Z_OK)
|
||||
bp2->bio_error = EILSEQ;
|
||||
|
||||
done:
|
||||
/* Finish processing the request. */
|
||||
free(bp->bio_data, M_GEOM_UZIP);
|
||||
@ -330,9 +413,9 @@ g_uzip_start(struct bio *bp)
|
||||
pp = bp->bio_to;
|
||||
gp = pp->geom;
|
||||
|
||||
DPRINTF(("%s/%s: %p: cmd=%d, offset=%jd, length=%jd, buffer=%p\n",
|
||||
__func__, gp->name, bp, bp->bio_cmd, (intmax_t)bp->bio_offset,
|
||||
(intmax_t)bp->bio_length, bp->bio_data));
|
||||
DPRINTF(GUZ_DBG_IO, ("%s/%s: %p: cmd=%d, offset=%jd, length=%jd, "
|
||||
"buffer=%p\n", __func__, gp->name, bp, bp->bio_cmd,
|
||||
(intmax_t)bp->bio_offset, (intmax_t)bp->bio_length, bp->bio_data));
|
||||
|
||||
sc = gp->softc;
|
||||
sc->req_total++;
|
||||
@ -392,6 +475,92 @@ g_uzip_spoiled(struct g_consumer *cp)
|
||||
g_wither_geom(gp, ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uzip_parse_toc(struct g_uzip_softc *sc, struct g_provider *pp,
|
||||
struct g_geom *gp)
|
||||
{
|
||||
uint32_t i, j, backref_to;
|
||||
uint64_t max_offset, min_offset;
|
||||
|
||||
min_offset = sizeof(struct cloop_header) +
|
||||
(sc->nblocks + 1) * sizeof(uint64_t);
|
||||
max_offset = sc->toc[0].offset - 1;
|
||||
for (i = 0; i < sc->nblocks; i++) {
|
||||
/* First do some bounds checking */
|
||||
if ((sc->toc[i].offset < min_offset) ||
|
||||
(sc->toc[i].offset >= pp->mediasize)) {
|
||||
goto error_offset;
|
||||
}
|
||||
DPRINTF_BLK(GUZ_DBG_IO, i, ("%s: cluster #%u "
|
||||
"sc->toc[i].offset=%ju max_offset=%ju\n", gp->name,
|
||||
(u_int)i, (uintmax_t)sc->toc[i].offset,
|
||||
(uintmax_t)max_offset));
|
||||
backref_to = BLEN_UNDEF;
|
||||
if (sc->toc[i].offset < max_offset) {
|
||||
/*
|
||||
* For the backref'ed blocks search already parsed
|
||||
* TOC entries for the matching offset and copy the
|
||||
* size from matched entry.
|
||||
*/
|
||||
for (j = 0; j <= i; j++) {
|
||||
if (sc->toc[j].offset == sc->toc[i].offset &&
|
||||
!BLK_IS_NIL(sc, j)) {
|
||||
break;
|
||||
}
|
||||
if (j != i) {
|
||||
continue;
|
||||
}
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: cannot match "
|
||||
"backref'ed offset at cluster #%u\n",
|
||||
gp->name, i));
|
||||
return (-1);
|
||||
}
|
||||
sc->toc[i].blen = sc->toc[j].blen;
|
||||
backref_to = j;
|
||||
} else {
|
||||
/*
|
||||
* For the "normal blocks" seek forward until we hit
|
||||
* block whose offset is larger than ours and assume
|
||||
* it's going to be the next one.
|
||||
*/
|
||||
for (j = i + 1; j < sc->nblocks; j++) {
|
||||
if (sc->toc[j].offset > max_offset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sc->toc[i].blen = sc->toc[j].offset -
|
||||
sc->toc[i].offset;
|
||||
if (BLK_ENDS(sc, i) > pp->mediasize) {
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: cluster #%u "
|
||||
"extends past media boundary (%ju > %ju)\n",
|
||||
gp->name, (u_int)i,
|
||||
(uintmax_t)BLK_ENDS(sc, i),
|
||||
(intmax_t)pp->mediasize));
|
||||
return (-1);
|
||||
}
|
||||
KASSERT(max_offset <= sc->toc[i].offset, (
|
||||
"%s: max_offset is incorrect: %ju",
|
||||
gp->name, (uintmax_t)max_offset));
|
||||
max_offset = BLK_ENDS(sc, i) - 1;
|
||||
}
|
||||
DPRINTF_BLK(GUZ_DBG_TOC, i, ("%s: cluster #%u, original %u "
|
||||
"bytes, in %u bytes", gp->name, i, sc->blksz,
|
||||
sc->toc[i].blen));
|
||||
if (backref_to != BLEN_UNDEF) {
|
||||
DPRINTF_BLK(GUZ_DBG_TOC, i, (" (->#%u)",
|
||||
(u_int)backref_to));
|
||||
}
|
||||
DPRINTF_BLK(GUZ_DBG_TOC, i, ("\n"));
|
||||
}
|
||||
return (0);
|
||||
|
||||
error_offset:
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: cluster #%u: invalid offset %ju, "
|
||||
"min_offset=%ju mediasize=%jd\n", gp->name, (u_int)i,
|
||||
sc->toc[i].offset, min_offset, pp->mediasize));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct g_geom *
|
||||
g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
{
|
||||
@ -403,6 +572,10 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
struct g_geom *gp;
|
||||
struct g_provider *pp2;
|
||||
struct g_uzip_softc *sc;
|
||||
enum {
|
||||
GEOM_UZIP = 1,
|
||||
GEOM_ULZMA
|
||||
} type;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, pp->name);
|
||||
g_topology_assert();
|
||||
@ -422,10 +595,7 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
if (error == 0)
|
||||
error = g_access(cp, 1, 0, 0);
|
||||
if (error) {
|
||||
g_detach(cp);
|
||||
g_destroy_consumer(cp);
|
||||
g_destroy_geom(gp);
|
||||
return (NULL);
|
||||
goto e1;
|
||||
}
|
||||
g_topology_unlock();
|
||||
|
||||
@ -433,22 +603,47 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
* Read cloop header, look for CLOOP magic, perform
|
||||
* other validity checks.
|
||||
*/
|
||||
DPRINTF(("%s: media sectorsize %u, mediasize %jd\n",
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: media sectorsize %u, mediasize %jd\n",
|
||||
gp->name, pp->sectorsize, (intmax_t)pp->mediasize));
|
||||
buf = g_read_data(cp, 0, pp->sectorsize, NULL);
|
||||
if (buf == NULL)
|
||||
goto err;
|
||||
goto e2;
|
||||
header = (struct cloop_header *) buf;
|
||||
if (strncmp(header->magic, CLOOP_MAGIC_START,
|
||||
sizeof(CLOOP_MAGIC_START) - 1) != 0) {
|
||||
DPRINTF(("%s: no CLOOP magic\n", gp->name));
|
||||
goto err;
|
||||
}
|
||||
if (header->magic[0x0b] != 'V' || header->magic[0x0c] < '2') {
|
||||
DPRINTF(("%s: image version too old\n", gp->name));
|
||||
goto err;
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: no CLOOP magic\n", gp->name));
|
||||
goto e3;
|
||||
}
|
||||
|
||||
switch (header->magic[CLOOP_OFS_COMPR]) {
|
||||
case CLOOP_COMP_LZMA:
|
||||
case CLOOP_COMP_LZMA_DDP:
|
||||
type = GEOM_ULZMA;
|
||||
if (header->magic[CLOOP_OFS_VERSN] < CLOOP_MINVER_LZMA) {
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: image version too old\n",
|
||||
gp->name));
|
||||
goto e3;
|
||||
}
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: GEOM_UZIP_LZMA image found\n",
|
||||
gp->name));
|
||||
break;
|
||||
case CLOOP_COMP_LIBZ:
|
||||
case CLOOP_COMP_LIBZ_DDP:
|
||||
type = GEOM_UZIP;
|
||||
if (header->magic[CLOOP_OFS_VERSN] < CLOOP_MINVER_ZLIB) {
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: image version too old\n",
|
||||
gp->name));
|
||||
goto e3;
|
||||
}
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: GEOM_UZIP_ZLIB image found\n",
|
||||
gp->name));
|
||||
break;
|
||||
default:
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: unsupported image type\n",
|
||||
gp->name));
|
||||
goto e3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize softc and read offsets.
|
||||
*/
|
||||
@ -459,7 +654,7 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
if (sc->blksz % 512 != 0) {
|
||||
printf("%s: block size (%u) should be multiple of 512.\n",
|
||||
gp->name, sc->blksz);
|
||||
goto err;
|
||||
goto e4;
|
||||
}
|
||||
if (sc->blksz > MAX_BLKSZ) {
|
||||
printf("%s: block size (%u) should not be larger than %d.\n",
|
||||
@ -470,15 +665,17 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
total_offsets * sizeof(uint64_t) > pp->mediasize) {
|
||||
printf("%s: media too small for %u blocks\n",
|
||||
gp->name, sc->nblocks);
|
||||
goto err;
|
||||
goto e4;
|
||||
}
|
||||
sc->offsets = malloc(
|
||||
total_offsets * sizeof(uint64_t), M_GEOM_UZIP, M_WAITOK);
|
||||
sc->toc = malloc(total_offsets * sizeof(struct g_uzip_blk),
|
||||
M_GEOM_UZIP, M_WAITOK | M_ZERO);
|
||||
offsets_read = MIN(total_offsets,
|
||||
(pp->sectorsize - sizeof(*header)) / sizeof(uint64_t));
|
||||
for (i = 0; i < offsets_read; i++)
|
||||
sc->offsets[i] = be64toh(((uint64_t *) (header + 1))[i]);
|
||||
DPRINTF(("%s: %u offsets in the first sector\n",
|
||||
for (i = 0; i < offsets_read; i++) {
|
||||
sc->toc[i].offset = be64toh(((uint64_t *) (header + 1))[i]);
|
||||
sc->toc[i].blen = BLEN_UNDEF;
|
||||
}
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: %u offsets in the first sector\n",
|
||||
gp->name, offsets_read));
|
||||
for (blk = 1; offsets_read < total_offsets; blk++) {
|
||||
uint32_t nread;
|
||||
@ -487,25 +684,59 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
buf = g_read_data(
|
||||
cp, blk * pp->sectorsize, pp->sectorsize, NULL);
|
||||
if (buf == NULL)
|
||||
goto err;
|
||||
goto e5;
|
||||
nread = MIN(total_offsets - offsets_read,
|
||||
pp->sectorsize / sizeof(uint64_t));
|
||||
DPRINTF(("%s: %u offsets read from sector %d\n",
|
||||
DPRINTF(GUZ_DBG_TOC, ("%s: %u offsets read from sector %d\n",
|
||||
gp->name, nread, blk));
|
||||
for (i = 0; i < nread; i++) {
|
||||
sc->offsets[offsets_read + i] =
|
||||
sc->toc[offsets_read + i].offset =
|
||||
be64toh(((uint64_t *) buf)[i]);
|
||||
sc->toc[offsets_read + i].blen = BLEN_UNDEF;
|
||||
}
|
||||
offsets_read += nread;
|
||||
}
|
||||
free(buf, M_GEOM);
|
||||
DPRINTF(("%s: done reading offsets\n", gp->name));
|
||||
buf = NULL;
|
||||
offsets_read -= 1;
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: done reading %u block offsets from %u "
|
||||
"sectors\n", gp->name, offsets_read, blk));
|
||||
if (sc->nblocks != offsets_read) {
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: read %s offsets than expected "
|
||||
"blocks\n", gp->name,
|
||||
sc->nblocks < offsets_read ? "more" : "less"));
|
||||
goto e5;
|
||||
}
|
||||
/* Massage TOC (table of contents), make sure it is sound */
|
||||
if (g_uzip_parse_toc(sc, pp, gp) != 0) {
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s: TOC error\n", gp->name));
|
||||
goto e5;
|
||||
}
|
||||
mtx_init(&sc->last_mtx, "geom_uzip cache", NULL, MTX_DEF);
|
||||
mtx_init(&sc->queue_mtx, "geom_uzip wrkthread", NULL, MTX_DEF);
|
||||
bioq_init(&sc->bio_queue);
|
||||
sc->last_blk = -1;
|
||||
sc->last_buf = malloc(sc->blksz, M_GEOM_UZIP, M_WAITOK);
|
||||
sc->req_total = 0;
|
||||
sc->req_cached = 0;
|
||||
|
||||
if (type == GEOM_UZIP) {
|
||||
sc->dcp = g_uzip_zlib_ctor(sc->blksz);
|
||||
} else {
|
||||
sc->dcp = g_uzip_lzma_ctor(sc->blksz);
|
||||
}
|
||||
if (sc->dcp == NULL) {
|
||||
goto e6;
|
||||
}
|
||||
|
||||
sc->uzip_do = &g_uzip_do;
|
||||
|
||||
error = kproc_create(g_uzip_wrkthr, sc, &sc->procp, 0, 0, "%s",
|
||||
gp->name);
|
||||
if (error != 0) {
|
||||
goto e7;
|
||||
}
|
||||
|
||||
g_topology_lock();
|
||||
pp2 = g_new_providerf(gp, "%s", gp->name);
|
||||
pp2->sectorsize = 512;
|
||||
@ -515,22 +746,31 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
g_error_provider(pp2, 0);
|
||||
g_access(cp, -1, 0, 0);
|
||||
|
||||
DPRINTF(("%s: taste ok (%d, %jd), (%d, %d), %x\n",
|
||||
gp->name,
|
||||
pp2->sectorsize, (intmax_t)pp2->mediasize,
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: taste ok (%d, %jd), (%d, %d), %x\n",
|
||||
gp->name, pp2->sectorsize, (intmax_t)pp2->mediasize,
|
||||
pp2->stripeoffset, pp2->stripesize, pp2->flags));
|
||||
DPRINTF(("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz));
|
||||
DPRINTF(GUZ_DBG_INFO, ("%s: %u x %u blocks\n", gp->name, sc->nblocks,
|
||||
sc->blksz));
|
||||
return (gp);
|
||||
|
||||
err:
|
||||
e7:
|
||||
sc->dcp->free(sc->dcp);
|
||||
e6:
|
||||
free(sc->last_buf, M_GEOM);
|
||||
mtx_destroy(&sc->queue_mtx);
|
||||
mtx_destroy(&sc->last_mtx);
|
||||
e5:
|
||||
free(sc->toc, M_GEOM);
|
||||
e4:
|
||||
free(gp->softc, M_GEOM_UZIP);
|
||||
e3:
|
||||
if (buf != NULL) {
|
||||
free(buf, M_GEOM);
|
||||
}
|
||||
e2:
|
||||
g_topology_lock();
|
||||
g_access(cp, -1, 0, 0);
|
||||
if (buf != NULL)
|
||||
free(buf, M_GEOM);
|
||||
if (gp->softc != NULL) {
|
||||
g_uzip_softc_free(gp->softc, NULL);
|
||||
gp->softc = NULL;
|
||||
}
|
||||
e1:
|
||||
g_detach(cp);
|
||||
g_destroy_consumer(cp);
|
||||
g_destroy_geom(gp);
|
||||
@ -547,7 +787,8 @@ g_uzip_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp)
|
||||
g_topology_assert();
|
||||
|
||||
if (gp->softc == NULL) {
|
||||
DPRINTF(("%s(%s): gp->softc == NULL\n", __func__, gp->name));
|
||||
DPRINTF(GUZ_DBG_ERR, ("%s(%s): gp->softc == NULL\n", __func__,
|
||||
gp->name));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
37
sys/geom/uzip/g_uzip.h
Normal file
37
sys/geom/uzip/g_uzip.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* Copyright (c) 2014 Juniper Networks, Inc.
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __GEOM_G_UZIP_H__
|
||||
#define __GEOM_G_UZIP_H__
|
||||
|
||||
MALLOC_DECLARE(M_GEOM_UZIP);
|
||||
|
||||
#define DEFINE_RAW_METHOD(func, rval, args...) typedef rval (*func##_t)(args)
|
||||
|
||||
#endif /* __GEOM_G_UZIP_H__ */
|
55
sys/geom/uzip/g_uzip_cloop.h
Normal file
55
sys/geom/uzip/g_uzip_cloop.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* CLOOP format and related constants */
|
||||
|
||||
/*
|
||||
* Integer values (block size, number of blocks, offsets)
|
||||
* are stored in big-endian (network) order on disk.
|
||||
*/
|
||||
|
||||
#define CLOOP_MAGIC_LEN 128
|
||||
#define CLOOP_OFS_COMPR 0x0b
|
||||
#define CLOOP_OFS_VERSN (CLOOP_OFS_COMPR + 1)
|
||||
|
||||
#define CLOOP_MAJVER_2 '2'
|
||||
#define CLOOP_MAJVER_3 '3'
|
||||
|
||||
#define CLOOP_COMP_LIBZ 'V'
|
||||
#define CLOOP_COMP_LIBZ_DDP 'v'
|
||||
#define CLOOP_COMP_LZMA 'L'
|
||||
#define CLOOP_COMP_LZMA_DDP 'l'
|
||||
|
||||
#define CLOOP_MINVER_LZMA CLOOP_MAJVER_3
|
||||
#define CLOOP_MINVER_ZLIB CLOOP_MAJVER_2
|
||||
|
||||
struct cloop_header {
|
||||
char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
};
|
41
sys/geom/uzip/g_uzip_dapi.h
Normal file
41
sys/geom/uzip/g_uzip_dapi.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct g_uzip_dapi;
|
||||
|
||||
DEFINE_RAW_METHOD(g_uzip_dapi_decompress, int, struct g_uzip_dapi *,
|
||||
const char *, void *, size_t, void *);
|
||||
DEFINE_RAW_METHOD(g_uzip_dapi_free, void, struct g_uzip_dapi *);
|
||||
DEFINE_RAW_METHOD(g_uzip_dapi_rewind, int, struct g_uzip_dapi *, const char *);
|
||||
|
||||
struct g_uzip_dapi {
|
||||
g_uzip_dapi_decompress_t decompress;
|
||||
g_uzip_dapi_free_t free;
|
||||
g_uzip_dapi_rewind_t rewind;
|
||||
void *pvt;
|
||||
};
|
111
sys/geom/uzip/g_uzip_lzma.c
Normal file
111
sys/geom/uzip/g_uzip_lzma.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* Copyright (c) 2014 Juniper Networks, Inc.
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* Copyright (c) 2010-2012 Aleksandr Rybalko
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <contrib/xz-embedded/linux/include/linux/xz.h>
|
||||
|
||||
#include <geom/uzip/g_uzip.h>
|
||||
#include <geom/uzip/g_uzip_dapi.h>
|
||||
#include <geom/uzip/g_uzip_lzma.h>
|
||||
|
||||
struct g_uzip_lzma {
|
||||
struct g_uzip_dapi pub;
|
||||
/* XZ decoder structs */
|
||||
struct xz_buf b;
|
||||
struct xz_dec *s;
|
||||
};
|
||||
|
||||
static int g_uzip_lzma_nop(struct g_uzip_dapi *, const char *);
|
||||
|
||||
static void
|
||||
g_uzip_lzma_free(struct g_uzip_dapi *lzpp)
|
||||
{
|
||||
struct g_uzip_lzma *lzp;
|
||||
|
||||
lzp = (struct g_uzip_lzma *)lzpp->pvt;
|
||||
if (lzp->s != NULL) {
|
||||
xz_dec_end(lzp->s);
|
||||
lzp->s = NULL;
|
||||
}
|
||||
|
||||
free(lzp, M_GEOM_UZIP);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uzip_lzma_decompress(struct g_uzip_dapi *lzpp, const char *gp_name,
|
||||
void *ibp, size_t ilen, void *obp)
|
||||
{
|
||||
struct g_uzip_lzma *lzp;
|
||||
int err;
|
||||
|
||||
lzp = (struct g_uzip_lzma *)lzpp->pvt;
|
||||
|
||||
lzp->b.in = ibp;
|
||||
lzp->b.out = obp;
|
||||
lzp->b.in_pos = lzp->b.out_pos = 0;
|
||||
lzp->b.in_size = ilen;
|
||||
lzp->b.out_size = (size_t)-1;
|
||||
err = (xz_dec_run(lzp->s, &lzp->b) != XZ_STREAM_END) ? 1 : 0;
|
||||
/* TODO decoder recovery, if needed */
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
struct g_uzip_dapi *
|
||||
g_uzip_lzma_ctor(uint32_t blksz)
|
||||
{
|
||||
struct g_uzip_lzma *lzp;
|
||||
|
||||
lzp = malloc(sizeof(struct g_uzip_lzma), M_GEOM_UZIP, M_WAITOK);
|
||||
xz_crc32_init();
|
||||
lzp->s = xz_dec_init(XZ_SINGLE, 0);
|
||||
if (lzp->s == NULL) {
|
||||
goto e1;
|
||||
}
|
||||
lzp->pub.decompress = &g_uzip_lzma_decompress;
|
||||
lzp->pub.free = &g_uzip_lzma_free;
|
||||
lzp->pub.rewind = &g_uzip_lzma_nop;
|
||||
lzp->pub.pvt = lzp;
|
||||
return (&lzp->pub);
|
||||
e1:
|
||||
free(lzp, M_GEOM_UZIP);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uzip_lzma_nop(struct g_uzip_dapi *zpp, const char *gp_name)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
32
sys/geom/uzip/g_uzip_lzma.h
Normal file
32
sys/geom/uzip/g_uzip_lzma.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* Copyright (c) 2014 Juniper Networks, Inc.
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* Copyright (c) 2010-2012 Aleksandr Rybalko
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct g_uzip_dapi *g_uzip_lzma_ctor(uint32_t);
|
56
sys/geom/uzip/g_uzip_softc.h
Normal file
56
sys/geom/uzip/g_uzip_softc.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* Copyright (c) 2014 Juniper Networks, Inc.
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct g_uzip_softc;
|
||||
struct bio;
|
||||
|
||||
DEFINE_RAW_METHOD(g_uzip_do, void, struct g_uzip_softc *, struct bio *);
|
||||
|
||||
struct g_uzip_softc {
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
struct g_uzip_blk *toc; /* table of contents */
|
||||
|
||||
struct mtx last_mtx;
|
||||
uint32_t last_blk; /* last blk no */
|
||||
char *last_buf; /* last blk data */
|
||||
int req_total; /* total requests */
|
||||
int req_cached; /* cached requests */
|
||||
struct g_uzip_dapi *dcp; /* decompressor instance */
|
||||
|
||||
g_uzip_do_t uzip_do;
|
||||
|
||||
struct proc *procp;
|
||||
struct bio_queue_head bio_queue;
|
||||
struct mtx queue_mtx;
|
||||
unsigned wrkthr_flags;
|
||||
#define GUZ_SHUTDOWN (0x1 << 0)
|
||||
#define GUZ_EXITING (0x1 << 1)
|
||||
};
|
71
sys/geom/uzip/g_uzip_wrkthr.c
Normal file
71
sys/geom/uzip/g_uzip_wrkthr.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*-
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sched.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <geom/uzip/g_uzip.h>
|
||||
#include <geom/uzip/g_uzip_softc.h>
|
||||
#include <geom/uzip/g_uzip_wrkthr.h>
|
||||
|
||||
void
|
||||
g_uzip_wrkthr(void *arg)
|
||||
{
|
||||
struct g_uzip_softc *sc;
|
||||
struct bio *bp;
|
||||
|
||||
sc = (struct g_uzip_softc *)arg;
|
||||
thread_lock(curthread);
|
||||
sched_prio(curthread, PRIBIO);
|
||||
thread_unlock(curthread);
|
||||
|
||||
for (;;) {
|
||||
mtx_lock(&sc->queue_mtx);
|
||||
if (sc->wrkthr_flags & GUZ_SHUTDOWN) {
|
||||
sc->wrkthr_flags |= GUZ_EXITING;
|
||||
mtx_unlock(&sc->queue_mtx);
|
||||
kproc_exit(0);
|
||||
}
|
||||
bp = bioq_takefirst(&sc->bio_queue);
|
||||
if (!bp) {
|
||||
msleep(sc, &sc->queue_mtx, PRIBIO | PDROP,
|
||||
"wrkwait", 0);
|
||||
continue;
|
||||
}
|
||||
mtx_unlock(&sc->queue_mtx);
|
||||
sc->uzip_do(sc, bp);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Nuxi, https://nuxi.nl/
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -25,4 +26,5 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
long cloudabi_convert_errno(long);
|
||||
void g_uzip_wrkthr(void *);
|
||||
|
137
sys/geom/uzip/g_uzip_zlib.c
Normal file
137
sys/geom/uzip/g_uzip_zlib.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* Copyright (c) 2014 Juniper Networks, Inc.
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <sys/zlib.h>
|
||||
|
||||
#include <geom/uzip/g_uzip.h>
|
||||
#include <geom/uzip/g_uzip_dapi.h>
|
||||
#include <geom/uzip/g_uzip_zlib.h>
|
||||
|
||||
struct g_uzip_zlib {
|
||||
uint32_t blksz;
|
||||
struct g_uzip_dapi pub;
|
||||
/* Zlib decoder structs */
|
||||
z_stream zs;
|
||||
};
|
||||
|
||||
static void *z_alloc(void *, u_int, u_int);
|
||||
static void z_free(void *, void *);
|
||||
static int g_uzip_zlib_rewind(struct g_uzip_dapi *, const char *);
|
||||
|
||||
static void
|
||||
g_uzip_zlib_free(struct g_uzip_dapi *zpp)
|
||||
{
|
||||
struct g_uzip_zlib *zp;
|
||||
|
||||
zp = (struct g_uzip_zlib *)zpp->pvt;
|
||||
inflateEnd(&zp->zs);
|
||||
free(zp, M_GEOM_UZIP);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uzip_zlib_decompress(struct g_uzip_dapi *zpp, const char *gp_name, void *ibp,
|
||||
size_t ilen, void *obp)
|
||||
{
|
||||
int err;
|
||||
struct g_uzip_zlib *zp;
|
||||
|
||||
zp = (struct g_uzip_zlib *)zpp->pvt;
|
||||
|
||||
zp->zs.next_in = ibp;
|
||||
zp->zs.avail_in = ilen;
|
||||
zp->zs.next_out = obp;
|
||||
zp->zs.avail_out = zp->blksz;
|
||||
|
||||
err = (inflate(&zp->zs, Z_FINISH) != Z_STREAM_END) ? 1 : 0;
|
||||
if (err != 0) {
|
||||
printf("%s: UZIP(zlib) inflate() failed\n", gp_name);
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uzip_zlib_rewind(struct g_uzip_dapi *zpp, const char *gp_name)
|
||||
{
|
||||
int err;
|
||||
struct g_uzip_zlib *zp;
|
||||
|
||||
zp = (struct g_uzip_zlib *)zpp->pvt;
|
||||
|
||||
err = 0;
|
||||
if (inflateReset(&zp->zs) != Z_OK) {
|
||||
printf("%s: UZIP(zlib) decoder reset failed\n", gp_name);
|
||||
err = 1;
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
struct g_uzip_dapi *
|
||||
g_uzip_zlib_ctor(uint32_t blksz)
|
||||
{
|
||||
struct g_uzip_zlib *zp;
|
||||
|
||||
zp = malloc(sizeof(struct g_uzip_zlib), M_GEOM_UZIP, M_WAITOK);
|
||||
zp->zs.zalloc = z_alloc;
|
||||
zp->zs.zfree = z_free;
|
||||
if (inflateInit(&zp->zs) != Z_OK) {
|
||||
goto e1;
|
||||
}
|
||||
zp->blksz = blksz;
|
||||
zp->pub.decompress = &g_uzip_zlib_decompress;
|
||||
zp->pub.free = &g_uzip_zlib_free;
|
||||
zp->pub.rewind = &g_uzip_zlib_rewind;
|
||||
zp->pub.pvt = (void *)zp;
|
||||
return (&zp->pub);
|
||||
e1:
|
||||
free(zp, M_GEOM_UZIP);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void *
|
||||
z_alloc(void *nil, u_int type, u_int size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = malloc(type * size, M_GEOM_UZIP, M_NOWAIT);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
z_free(void *nil, void *ptr)
|
||||
{
|
||||
|
||||
free(ptr, M_GEOM_UZIP);
|
||||
}
|
33
sys/geom/uzip/g_uzip_zlib.h
Normal file
33
sys/geom/uzip/g_uzip_zlib.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Max Khon
|
||||
* Copyright (c) 2014 Juniper Networks, Inc.
|
||||
* Copyright (c) 2006-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct g_geom;
|
||||
|
||||
struct g_uzip_dapi *g_uzip_zlib_ctor(uint32_t);
|
@ -422,7 +422,7 @@ sysctl_hostid(SYSCTL_HANDLER_ARGS)
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_kern, KERN_HOSTID, hostid,
|
||||
CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
|
||||
CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE | CTLFLAG_CAPRD,
|
||||
NULL, 0, sysctl_hostid, "LU", "Host ID");
|
||||
|
||||
/*
|
||||
|
@ -49,11 +49,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -43,11 +43,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -46,8 +46,8 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -64,7 +64,7 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -43,11 +43,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -38,9 +38,9 @@ options NO_SWAPPING
|
||||
# options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Not enough space for these..
|
||||
nooptions INVARIANTS
|
||||
|
@ -26,9 +26,9 @@ options AR71XX_ENV_UBOOT
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
@ -27,9 +27,9 @@ options AR71XX_ENV_UBOOT
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
@ -45,11 +45,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -38,8 +38,8 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -51,4 +51,4 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -41,8 +41,8 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -52,7 +52,7 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -54,11 +54,11 @@ options NO_SYSCTL_DESCR
|
||||
|
||||
# GEOM modules
|
||||
device geom_map # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem hackery!
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip # compressed in-memory filesystem hackery!
|
||||
options GEOM_UZIP
|
||||
options GEOM_PART_GPT
|
||||
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
options AR71XX_REALMEM=64*1024*1024
|
||||
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
@ -48,7 +48,7 @@ options AR71XX_ENV_UBOOT
|
||||
device geom_map
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
options GEOM_UNCOMPRESS
|
||||
options GEOM_UZIP
|
||||
options GEOM_PART_GPT
|
||||
|
||||
# yes, this board has a PCI connected atheros device
|
||||
@ -58,11 +58,11 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# In order to netboot, you have to build the mfsroot into the kernel
|
||||
# 19443712 or 19M is the biggest rootfs via netboot this thing supports
|
||||
#options MD_ROOT # md device usable as a potential root device
|
||||
#options MD_ROOT_SIZE=19444
|
||||
#makeoptions MFS_IMAGE=/tftpboot/mfsroot-dir825c1.img.ulzma
|
||||
#options ROOTDEVNAME=\"ufs:md0.uncompress\"
|
||||
#options ROOTDEVNAME=\"ufs:md0.uzip\"
|
||||
|
@ -26,9 +26,9 @@ options AR71XX_ENV_UBOOT
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
@ -65,7 +65,7 @@ options PSEUDOFS #Pseudo-filesystem framework
|
||||
#options BOOTP_WIRED_TO=rt0
|
||||
#options BOOTP_COMPAT
|
||||
#options CD9660 # ISO 9660 Filesystem
|
||||
#options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uncompress\"
|
||||
#options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uzip\"
|
||||
#options TMPFS # TMP Memory Filesystem
|
||||
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
@ -93,7 +93,7 @@ options FFS #Berkeley Fast Filesystem
|
||||
options MROUTING # Multicast routing
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
||||
options GEOM_UNCOMPRESS
|
||||
options GEOM_UZIP
|
||||
options MD_ROOT
|
||||
options ROOTDEVNAME=\"ufs:da0s1\"
|
||||
|
||||
|
@ -45,11 +45,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -32,11 +32,11 @@ options AR71XX_REALMEM=64*1024*1024
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -54,9 +54,9 @@ options FFS #Berkeley Fast Filesystem
|
||||
#options UFS_DIRHASH #Improve performance on big directories
|
||||
|
||||
# Support uncompress lzma rootfs
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# PCI bus
|
||||
device pci
|
||||
|
@ -38,9 +38,9 @@ options NO_SWAPPING
|
||||
# options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Not enough space for these..
|
||||
nooptions INVARIANTS
|
||||
|
@ -14,8 +14,8 @@ hints "ROUTERSTATION.hints"
|
||||
|
||||
# GEOM modules
|
||||
device geom_redboot # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem support
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip # compressed in-memory filesystem support
|
||||
options GEOM_UZIP
|
||||
|
||||
# For DOS
|
||||
options MSDOSFS
|
||||
@ -27,4 +27,4 @@ device etherswitch
|
||||
device ukswitch
|
||||
|
||||
# Boot path - redboot MFS
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uzip\"
|
||||
|
@ -15,8 +15,8 @@ device pcf2123_rtc
|
||||
|
||||
# GEOM modules
|
||||
device geom_redboot # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem support
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip # compressed in-memory filesystem support
|
||||
options GEOM_UZIP
|
||||
|
||||
# For DOS
|
||||
options MSDOSFS
|
||||
@ -28,5 +28,5 @@ device etherswitch
|
||||
device arswitch
|
||||
|
||||
# Boot off of flash
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uzip\"
|
||||
|
||||
|
@ -64,7 +64,7 @@ options BOOTP_NFSV3
|
||||
options BOOTP_WIRED_TO=rt0
|
||||
options BOOTP_COMPAT
|
||||
options CD9660 # ISO 9660 Filesystem
|
||||
options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uzip\"
|
||||
options TMPFS # TMP Memory Filesystem
|
||||
|
||||
#options FFS #Berkeley Fast Filesystem
|
||||
|
@ -67,10 +67,10 @@ options TMPFS # TMP Memory Filesystem
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
#options ROOTDEVNAME=\"nfs:193.178.153.200:/bsdmips\"
|
||||
|
||||
#device geom_uncompress
|
||||
#options GEOM_UNCOMPRESS
|
||||
#device geom_uzip
|
||||
#options GEOM_UZIP
|
||||
#options MD_ROOT
|
||||
#options ROOTDEVNAME=\"ufs:md0.uncompress\"
|
||||
#options ROOTDEVNAME=\"ufs:md0.uzip\"
|
||||
|
||||
# Options for making kernel less hangry
|
||||
makeoptions INLINE_LIMIT=1024
|
||||
|
@ -46,8 +46,8 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -64,7 +64,7 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -38,8 +38,8 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -51,4 +51,4 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -34,8 +34,8 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -47,7 +47,7 @@ device geom_map
|
||||
#options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -43,13 +43,13 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
# options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
# options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
# Note: we don't fit in 4MB flash, so the rootfs must be on USB for now
|
||||
options ROOTDEVNAME=\"ufs:da0\"
|
||||
|
@ -37,14 +37,14 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uncompress - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# We bite the performance overhead for now; the kernel won't
|
||||
# fit if the mutexes are inlined.
|
||||
|
@ -26,9 +26,9 @@ options BOOTVERBOSE
|
||||
|
||||
# GEOM modules
|
||||
device geom_map # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem hackery!
|
||||
device geom_uzip # compressed in-memory filesystem hackery!
|
||||
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
options AR71XX_ATH_EEPROM # Fetch EEPROM/PCI config from flash
|
||||
options ATH_EEPROM_FIRMWARE # Use EEPROM from flash
|
||||
|
@ -25,10 +25,10 @@ options AR71XX_ENV_UBOOT
|
||||
options BOOTVERBOSE
|
||||
|
||||
# GEOM modules
|
||||
device geom_uncompress # compressed in-memory filesystem hackery!
|
||||
device geom_uzip # compressed in-memory filesystem hackery!
|
||||
device geom_map # to get access to the SPI flash partitions
|
||||
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
options AR71XX_ATH_EEPROM # Fetch EEPROM/PCI config from flash
|
||||
options ATH_EEPROM_FIRMWARE # Use EEPROM from flash
|
||||
|
@ -21,7 +21,6 @@ SUBDIR= geom_bde \
|
||||
geom_sched \
|
||||
geom_shsec \
|
||||
geom_stripe \
|
||||
geom_uncompress \
|
||||
geom_uzip \
|
||||
geom_vinum \
|
||||
geom_virstor \
|
||||
|
@ -1,17 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../geom/uncompress \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/freebsd/ \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/linux/lib/xz/ \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/linux/include/linux/ \
|
||||
${.CURDIR}/../../../net
|
||||
|
||||
KMOD= geom_uncompress
|
||||
CFLAGS+= -I${.CURDIR}/../../../geom/uncompress/ \
|
||||
-I${.CURDIR}/../../../contrib/xz-embedded/freebsd \
|
||||
-I${.CURDIR}/../../../contrib/xz-embedded/linux/lib/xz/
|
||||
SRCS= g_uncompress.c xz_crc32.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c \
|
||||
xz_malloc.c
|
||||
SRCS+= xz.h xz_config.h xz_lzma2.h xz_malloc.h xz_private.h xz_stream.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -3,7 +3,20 @@
|
||||
.PATH: ${.CURDIR}/../../../geom/uzip ${.CURDIR}/../../../net
|
||||
|
||||
KMOD= geom_uzip
|
||||
SRCS= g_uzip.c
|
||||
SRCS= g_uzip.c g_uzip_zlib.c g_uzip_lzma.c g_uzip_wrkthr.c
|
||||
SRCS+= g_uzip.h g_uzip_dapi.h g_uzip_lzma.h g_uzip_zlib.h g_uzip_softc.h \
|
||||
g_uzip_wrkthr.h
|
||||
#CFLAGS= -g -DINVARIANT_SUPPORT -DINVARIANTS
|
||||
|
||||
.PATH: ${.CURDIR}/../../../contrib/xz-embedded/freebsd/ \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/linux/lib/xz/ \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/linux/include/linux/ \
|
||||
${.CURDIR}/../../../net
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../../contrib/xz-embedded/freebsd \
|
||||
-I${.CURDIR}/../../../contrib/xz-embedded/linux/lib/xz/
|
||||
SRCS+= xz_crc32.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c \
|
||||
xz_malloc.c
|
||||
SRCS+= xz.h xz_config.h xz_lzma2.h xz_malloc.h xz_private.h xz_stream.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -2683,7 +2683,6 @@ ieee80211_node_leave(struct ieee80211_node *ni)
|
||||
|
||||
IEEE80211_LOCK(ic);
|
||||
IEEE80211_AID_CLR(vap, ni->ni_associd);
|
||||
ni->ni_associd = 0;
|
||||
vap->iv_sta_assoc--;
|
||||
ic->ic_sta_assoc--;
|
||||
|
||||
|
@ -2453,4 +2453,4 @@ static moduledata_t new_tcp_fastpaths = {
|
||||
};
|
||||
|
||||
MODULE_VERSION(kern_tcpfastpaths, 1);
|
||||
DECLARE_MODULE(kern_tcpfastpaths, new_tcp_fastpaths, SI_SUB_PSEUDO, SI_ORDER_ANY);
|
||||
DECLARE_MODULE(kern_tcpfastpaths, new_tcp_fastpaths, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
|
||||
|
@ -263,9 +263,20 @@ static struct tcp_function_block tcp_def_funcblk = {
|
||||
0
|
||||
};
|
||||
|
||||
int t_functions_inited = 0;
|
||||
struct tcp_funchead t_functions;
|
||||
static struct tcp_function_block *tcp_func_set_ptr = &tcp_def_funcblk;
|
||||
|
||||
static void
|
||||
init_tcp_functions(void)
|
||||
{
|
||||
if (t_functions_inited == 0) {
|
||||
TAILQ_INIT(&t_functions);
|
||||
rw_init_flags(&tcp_function_lock, "tcp_func_lock" , 0);
|
||||
t_functions_inited = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct tcp_function_block *
|
||||
find_tcp_functions_locked(struct tcp_function_set *fs)
|
||||
{
|
||||
@ -503,6 +514,9 @@ register_tcp_functions(struct tcp_function_block *blk, int wait)
|
||||
struct tcp_function *n;
|
||||
struct tcp_function_set fs;
|
||||
|
||||
if (t_functions_inited == 0) {
|
||||
init_tcp_functions();
|
||||
}
|
||||
if ((blk->tfb_tcp_output == NULL) ||
|
||||
(blk->tfb_tcp_do_segment == NULL) ||
|
||||
(blk->tfb_tcp_ctloutput == NULL) ||
|
||||
@ -681,8 +695,7 @@ tcp_init(void)
|
||||
tcp_finwait2_timeout = TCPTV_FINWAIT2_TIMEOUT;
|
||||
tcp_tcbhashsize = hashsize;
|
||||
/* Setup the tcp function block list */
|
||||
TAILQ_INIT(&t_functions);
|
||||
rw_init_flags(&tcp_function_lock, "tcp_func_lock" , 0);
|
||||
init_tcp_functions();
|
||||
register_tcp_functions(&tcp_def_funcblk, M_WAITOK);
|
||||
|
||||
if (tcp_soreceive_stream) {
|
||||
|
@ -1009,6 +1009,7 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
||||
stcb = LIST_FIRST(&inp->sctp_asoc_list);
|
||||
if (stcb == NULL) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
@ -1028,6 +1029,7 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
||||
if ((!fnd) || (sin_a6 == NULL)) {
|
||||
/* punt */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ ffs_truncate(vp, length, flags, cred)
|
||||
struct inode *ip;
|
||||
ufs2_daddr_t bn, lbn, lastblock, lastiblock[NIADDR], indir_lbn[NIADDR];
|
||||
ufs2_daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR];
|
||||
ufs2_daddr_t count, blocksreleased = 0, datablocks;
|
||||
ufs2_daddr_t count, blocksreleased = 0, datablocks, blkno;
|
||||
struct bufobj *bo;
|
||||
struct fs *fs;
|
||||
struct buf *bp;
|
||||
@ -192,7 +192,7 @@ ffs_truncate(vp, length, flags, cred)
|
||||
int softdeptrunc, journaltrunc;
|
||||
int needextclean, extblocks;
|
||||
int offset, size, level, nblocks;
|
||||
int i, error, allerror;
|
||||
int i, error, allerror, indiroff;
|
||||
off_t osize;
|
||||
|
||||
ip = VTOI(vp);
|
||||
@ -329,16 +329,57 @@ ffs_truncate(vp, length, flags, cred)
|
||||
ip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (ffs_update(vp, !DOINGASYNC(vp)));
|
||||
}
|
||||
if (DOINGSOFTDEP(vp)) {
|
||||
/*
|
||||
* Lookup block number for a given offset. Zero length files
|
||||
* have no blocks, so return a blkno of -1.
|
||||
*/
|
||||
lbn = lblkno(fs, length - 1);
|
||||
if (length == 0) {
|
||||
blkno = -1;
|
||||
} else if (lbn < NDADDR) {
|
||||
blkno = DIP(ip, i_db[lbn]);
|
||||
} else {
|
||||
error = UFS_BALLOC(vp, lblktosize(fs, (off_t)lbn), fs->fs_bsize,
|
||||
cred, BA_METAONLY, &bp);
|
||||
if (error)
|
||||
return (error);
|
||||
indiroff = (lbn - NDADDR) % NINDIR(fs);
|
||||
if (ip->i_ump->um_fstype == UFS1)
|
||||
blkno = ((ufs1_daddr_t *)(bp->b_data))[indiroff];
|
||||
else
|
||||
blkno = ((ufs2_daddr_t *)(bp->b_data))[indiroff];
|
||||
/*
|
||||
* If the block number is non-zero, then the indirect block
|
||||
* must have been previously allocated and need not be written.
|
||||
* If the block number is zero, then we may have allocated
|
||||
* the indirect block and hence need to write it out.
|
||||
*/
|
||||
if (blkno != 0)
|
||||
brelse(bp);
|
||||
else if (DOINGSOFTDEP(vp) || DOINGASYNC(vp))
|
||||
bdwrite(bp);
|
||||
else
|
||||
bwrite(bp);
|
||||
}
|
||||
/*
|
||||
* If the block number at the new end of the file is zero,
|
||||
* then we must allocate it to ensure that the last block of
|
||||
* the file is allocated. Soft updates does not handle this
|
||||
* case, so here we have to clean up the soft updates data
|
||||
* structures describing the allocation past the truncation
|
||||
* point. Finding and deallocating those structures is a lot of
|
||||
* work. Since partial truncation with a hole at the end occurs
|
||||
* rarely, we solve the problem by syncing the file so that it
|
||||
* will have no soft updates data structures left.
|
||||
*/
|
||||
if (blkno == 0 && (error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0)
|
||||
return (error);
|
||||
if (blkno != 0 && DOINGSOFTDEP(vp)) {
|
||||
if (softdeptrunc == 0 && journaltrunc == 0) {
|
||||
/*
|
||||
* If a file is only partially truncated, then
|
||||
* we have to clean up the data structures
|
||||
* describing the allocation past the truncation
|
||||
* point. Finding and deallocating those structures
|
||||
* is a lot of work. Since partial truncation occurs
|
||||
* rarely, we solve the problem by syncing the file
|
||||
* so that it will have no data structures left.
|
||||
* If soft updates cannot handle this truncation,
|
||||
* clean up soft dependency data structures and
|
||||
* fall through to the synchronous truncation.
|
||||
*/
|
||||
if ((error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0)
|
||||
return (error);
|
||||
@ -358,15 +399,17 @@ ffs_truncate(vp, length, flags, cred)
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Shorten the size of the file. If the file is not being
|
||||
* truncated to a block boundary, the contents of the
|
||||
* partial block following the end of the file must be
|
||||
* zero'ed in case it ever becomes accessible again because
|
||||
* of subsequent file growth. Directories however are not
|
||||
* Shorten the size of the file. If the last block of the
|
||||
* shortened file is unallocated, we must allocate it.
|
||||
* Additionally, if the file is not being truncated to a
|
||||
* block boundary, the contents of the partial block
|
||||
* following the end of the file must be zero'ed in
|
||||
* case it ever becomes accessible again because of
|
||||
* subsequent file growth. Directories however are not
|
||||
* zero'ed as they should grow back initialized to empty.
|
||||
*/
|
||||
offset = blkoff(fs, length);
|
||||
if (offset == 0) {
|
||||
if (blkno != 0 && offset == 0) {
|
||||
ip->i_size = length;
|
||||
DIP_SET(ip, i_size, length);
|
||||
} else {
|
||||
@ -390,7 +433,7 @@ ffs_truncate(vp, length, flags, cred)
|
||||
ip->i_size = length;
|
||||
DIP_SET(ip, i_size, length);
|
||||
size = blksize(fs, ip, lbn);
|
||||
if (vp->v_type != VDIR)
|
||||
if (vp->v_type != VDIR && offset != 0)
|
||||
bzero((char *)bp->b_data + offset,
|
||||
(u_int)(size - offset));
|
||||
/* Kirk's code has reallocbuf(bp, size, 1) here */
|
||||
|
@ -166,7 +166,7 @@ clkintr(void *arg)
|
||||
mtx_unlock_spin(&clock_lock);
|
||||
}
|
||||
|
||||
if (sc && sc->et.et_active && sc->mode != MODE_STOP)
|
||||
if (sc->et.et_active && sc->mode != MODE_STOP)
|
||||
sc->et.et_event_cb(&sc->et, sc->et.et_arg);
|
||||
|
||||
#ifdef DEV_MCA
|
||||
|
@ -297,7 +297,6 @@ DIRDEPS+= \
|
||||
usr.bin/mklocale \
|
||||
usr.bin/mkstr \
|
||||
usr.bin/mktemp \
|
||||
usr.bin/mkulzma \
|
||||
usr.bin/mkuzip \
|
||||
usr.bin/msgs \
|
||||
usr.bin/mt \
|
||||
|
@ -99,7 +99,6 @@ SUBDIR= alias \
|
||||
mkimg \
|
||||
mklocale \
|
||||
mktemp \
|
||||
mkulzma \
|
||||
mkuzip \
|
||||
mt \
|
||||
ncal \
|
||||
|
@ -142,28 +142,6 @@ static struct ktr_header ktr_header;
|
||||
c = ','; \
|
||||
} while (0)
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
|
||||
void linux_ktrsysret(struct ktr_sysret *, u_int);
|
||||
|
||||
/*
|
||||
* from linux.h
|
||||
* Linux syscalls return negative errno's, we do positive and map them
|
||||
*/
|
||||
static int bsd_to_linux_errno[ELAST + 1] = {
|
||||
-0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
|
||||
-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
|
||||
-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
|
||||
-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
|
||||
-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
|
||||
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
|
||||
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
|
||||
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
|
||||
-6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
|
||||
-72, -67, -71
|
||||
};
|
||||
#endif
|
||||
|
||||
struct proc_info
|
||||
{
|
||||
TAILQ_ENTRY(proc_info) info;
|
||||
@ -393,13 +371,7 @@ main(int argc, char *argv[])
|
||||
ktrsyscall((struct ktr_syscall *)m, sv_flags);
|
||||
break;
|
||||
case KTR_SYSRET:
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
|
||||
linux_ktrsysret((struct ktr_sysret *)m,
|
||||
sv_flags);
|
||||
else
|
||||
#endif
|
||||
ktrsysret((struct ktr_sysret *)m, sv_flags);
|
||||
ktrsysret((struct ktr_sysret *)m, sv_flags);
|
||||
break;
|
||||
case KTR_NAMEI:
|
||||
case KTR_SYSCTL:
|
||||
@ -1366,7 +1338,8 @@ ktrsysret(struct ktr_sysret *ktr, u_int sv_flags)
|
||||
else if (error == EJUSTRETURN)
|
||||
printf("JUSTRETURN");
|
||||
else {
|
||||
printf("-1 errno %d", ktr->ktr_error);
|
||||
printf("-1 errno %d", sysdecode_freebsd_to_abi_errno(
|
||||
syscallabi(sv_flags), error));
|
||||
if (fancy)
|
||||
printf(" %s", strerror(ktr->ktr_error));
|
||||
}
|
||||
@ -1852,44 +1825,6 @@ ktrfaultend(struct ktr_faultend *ktr)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
void
|
||||
linux_ktrsysret(struct ktr_sysret *ktr, u_int sv_flags)
|
||||
{
|
||||
register_t ret = ktr->ktr_retval;
|
||||
int error = ktr->ktr_error;
|
||||
|
||||
syscallname(ktr->ktr_code, sv_flags);
|
||||
printf(" ");
|
||||
|
||||
if (error == 0) {
|
||||
if (fancy) {
|
||||
printf("%ld", (long)ret);
|
||||
if (ret < 0 || ret > 9)
|
||||
printf("/%#lx", (unsigned long)ret);
|
||||
} else {
|
||||
if (decimal)
|
||||
printf("%ld", (long)ret);
|
||||
else
|
||||
printf("%#lx", (unsigned long)ret);
|
||||
}
|
||||
} else if (error == ERESTART)
|
||||
printf("RESTART");
|
||||
else if (error == EJUSTRETURN)
|
||||
printf("JUSTRETURN");
|
||||
else {
|
||||
if (ktr->ktr_error <= ELAST + 1)
|
||||
error = abs(bsd_to_linux_errno[ktr->ktr_error]);
|
||||
else
|
||||
error = 999;
|
||||
printf("-1 errno %d", error);
|
||||
if (fancy)
|
||||
printf(" %s", strerror(ktr->ktr_error));
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
|
@ -1,8 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= mkulzma
|
||||
MAN= mkulzma.8
|
||||
|
||||
LIBADD= lzma
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,20 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
gnu/lib/csu \
|
||||
gnu/lib/libgcc \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libc \
|
||||
lib/libcompiler_rt \
|
||||
lib/liblzma \
|
||||
lib/libthr \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
@ -1,107 +0,0 @@
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\" Derived from mkuzip.8 by Aleksandr Rybalko <ray@ddteam.net>
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\" "THE BEER-WARE LICENSE" (Revision 42):
|
||||
.\" <sobomax@FreeBSD.ORG> wrote this file. As long as you retain this notice you
|
||||
.\" can do whatever you want with this stuff. If we meet some day, and you think
|
||||
.\" this stuff is worth it, you can buy me a beer in return. Maxim Sobolev
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 17, 2006
|
||||
.Dt MKULZMA 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mkulzma
|
||||
.Nd compress disk image for use with
|
||||
.Xr geom_uncompress 4
|
||||
class
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl v
|
||||
.Op Fl o Ar outfile
|
||||
.Op Fl s Ar cluster_size
|
||||
.Ar infile
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility compresses a disk image file so that the
|
||||
.Xr geom_uncompress 4
|
||||
class will be able to decompress the resulting image at run-time.
|
||||
This allows for a significant reduction of size of disk image at
|
||||
the expense of some CPU time required to decompress the data each
|
||||
time it is read.
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
works in two phases:
|
||||
.Bl -enum
|
||||
.It
|
||||
An
|
||||
.Ar infile
|
||||
image is split into clusters; each cluster is compressed using liblzma.
|
||||
.It
|
||||
The resulting set of compressed clusters along with headers that allow
|
||||
locating each individual cluster is written to the output file.
|
||||
.El
|
||||
.Pp
|
||||
The options are:
|
||||
.Bl -tag -width indent
|
||||
.It Fl o Ar outfile
|
||||
Name of the output file
|
||||
.Ar outfile .
|
||||
The default is to use the input name with the suffix
|
||||
.Pa .ulzma .
|
||||
.It Fl s Ar cluster_size
|
||||
Split the image into clusters of
|
||||
.Ar cluster_size
|
||||
bytes, 16384 bytes by default.
|
||||
The
|
||||
.Ar cluster_size
|
||||
should be a multiple of 512 bytes.
|
||||
.It Fl v
|
||||
Display verbose messages.
|
||||
.El
|
||||
.Sh NOTES
|
||||
The compression ratio largely depends on the cluster size used.
|
||||
.\" The following two sentences are unclear: how can xz(1) be
|
||||
.\" used in a comparable fashion, and wouldn't a lzma-compressed
|
||||
.\" image suffer from larger cluster sizes as well?
|
||||
For large cluster sizes (16K and higher), typical compression ratios
|
||||
are only 1-2% less than those achieved with
|
||||
.Xr lzma 1 .
|
||||
However, it should be kept in mind that larger cluster
|
||||
sizes lead to higher overhead in the
|
||||
.Xr geom_uncompress 4
|
||||
class, as the class has to decompress the whole cluster even if
|
||||
only a few bytes from that cluster have to be read.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
inserts a short shell script at the beginning of the generated image,
|
||||
which makes it possible to
|
||||
.Dq run
|
||||
the image just like any other shell script.
|
||||
The script tries to load the
|
||||
.Xr geom_uncompress 4
|
||||
class if it is not loaded, configure the image as an
|
||||
.Xr md 4
|
||||
disk device using
|
||||
.Xr mdconfig 8 ,
|
||||
and automatically mount it using
|
||||
.Xr mount_cd9660 8
|
||||
on the mount point provided as the first argument to the script.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr lzma 1 ,
|
||||
.Xr geom 4 ,
|
||||
.Xr geom_uncompress 4 ,
|
||||
.Xr md 4 ,
|
||||
.Xr mdconfig 8 ,
|
||||
.Xr mount_cd9660 8
|
||||
.Sh AUTHORS
|
||||
.An Maxim Sobolev Aq Mt sobomax@FreeBSD.org
|
||||
.An Aleksandr Rybalko Aq Mt ray@ddteam.net
|
@ -1,330 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Derived from mkuzip.c by Aleksandr Rybalko <ray@ddteam.net>
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <sobomax@FreeBSD.ORG> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Maxim Sobolev
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/disk.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <lzma.h>
|
||||
|
||||
#define CLSTSIZE 16384
|
||||
#define DEFAULT_SUFX ".ulzma"
|
||||
|
||||
#define USED_BLOCKSIZE DEV_BSIZE
|
||||
|
||||
#define CLOOP_MAGIC_LEN 128
|
||||
/* Format L3.0, since we move to XZ API */
|
||||
static char CLOOP_MAGIC_START[] =
|
||||
"#!/bin/sh\n"
|
||||
"#L3.0\n"
|
||||
"n=uncompress\n"
|
||||
"m=geom_$n\n"
|
||||
"(kldstat -m $m 2>&-||kldload $m)>&-&&"
|
||||
"mount_cd9660 /dev/`mdconfig -af $0`.$n $1\n"
|
||||
"exit $?\n";
|
||||
|
||||
static char *readblock(int, char *, u_int32_t);
|
||||
static void usage(void);
|
||||
static void *safe_malloc(size_t);
|
||||
static void cleanup(void);
|
||||
|
||||
static char *cleanfile = NULL;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *iname, *oname, *obuf, *ibuf;
|
||||
int fdr, fdw, i, opt, verbose, tmp;
|
||||
struct iovec iov[2];
|
||||
struct stat sb;
|
||||
uint32_t destlen;
|
||||
uint64_t offset;
|
||||
uint64_t *toc;
|
||||
lzma_filter filters[2];
|
||||
lzma_options_lzma opt_lzma;
|
||||
lzma_ret ret;
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
struct cloop_header {
|
||||
char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
} hdr;
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
hdr.blksz = CLSTSIZE;
|
||||
strcpy(hdr.magic, CLOOP_MAGIC_START);
|
||||
oname = NULL;
|
||||
verbose = 0;
|
||||
|
||||
while((opt = getopt(argc, argv, "o:s:v")) != -1) {
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
oname = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
tmp = atoi(optarg);
|
||||
if (tmp <= 0) {
|
||||
errx(1,
|
||||
"invalid cluster size specified: %s",
|
||||
optarg);
|
||||
/* Not reached */
|
||||
}
|
||||
if (tmp % USED_BLOCKSIZE != 0) {
|
||||
errx(1,
|
||||
"cluster size should be multiple of %d",
|
||||
USED_BLOCKSIZE);
|
||||
/* Not reached */
|
||||
}
|
||||
if ( tmp > MAXPHYS) {
|
||||
errx(1, "cluster size is too large");
|
||||
/* Not reached */
|
||||
}
|
||||
hdr.blksz = tmp;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* Not reached */
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1) {
|
||||
usage();
|
||||
/* Not reached */
|
||||
}
|
||||
|
||||
iname = argv[0];
|
||||
if (oname == NULL) {
|
||||
asprintf(&oname, "%s%s", iname, DEFAULT_SUFX);
|
||||
if (oname == NULL) {
|
||||
err(1, "can't allocate memory");
|
||||
/* Not reached */
|
||||
}
|
||||
}
|
||||
|
||||
obuf = safe_malloc(hdr.blksz*2);
|
||||
ibuf = safe_malloc(hdr.blksz);
|
||||
|
||||
signal(SIGHUP, exit);
|
||||
signal(SIGINT, exit);
|
||||
signal(SIGTERM, exit);
|
||||
signal(SIGXCPU, exit);
|
||||
signal(SIGXFSZ, exit);
|
||||
atexit(cleanup);
|
||||
|
||||
fdr = open(iname, O_RDONLY);
|
||||
if (fdr < 0) {
|
||||
err(1, "open(%s)", iname);
|
||||
/* Not reached */
|
||||
}
|
||||
if (fstat(fdr, &sb) != 0) {
|
||||
err(1, "fstat(%s)", iname);
|
||||
/* Not reached */
|
||||
}
|
||||
if (S_ISCHR(sb.st_mode)) {
|
||||
off_t ms;
|
||||
|
||||
if (ioctl(fdr, DIOCGMEDIASIZE, &ms) < 0) {
|
||||
err(1, "ioctl(DIOCGMEDIASIZE)");
|
||||
/* Not reached */
|
||||
}
|
||||
sb.st_size = ms;
|
||||
} else if (!S_ISREG(sb.st_mode)) {
|
||||
fprintf(stderr,
|
||||
"%s: not a character device or regular file\n",
|
||||
iname);
|
||||
exit(1);
|
||||
}
|
||||
hdr.nblocks = sb.st_size / hdr.blksz;
|
||||
if ((sb.st_size % hdr.blksz) != 0) {
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "file size is not multiple "
|
||||
"of %d, padding data\n", hdr.blksz);
|
||||
hdr.nblocks++;
|
||||
}
|
||||
toc = safe_malloc((hdr.nblocks + 1) * sizeof(*toc));
|
||||
|
||||
fdw = open(oname, O_WRONLY | O_TRUNC | O_CREAT,
|
||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
if (fdw < 0) {
|
||||
err(1, "open(%s)", oname);
|
||||
/* Not reached */
|
||||
}
|
||||
cleanfile = oname;
|
||||
|
||||
/*
|
||||
* Prepare header that we will write later when we have index ready.
|
||||
*/
|
||||
iov[0].iov_base = (char *)&hdr;
|
||||
iov[0].iov_len = sizeof(hdr);
|
||||
iov[1].iov_base = (char *)toc;
|
||||
iov[1].iov_len = (hdr.nblocks + 1) * sizeof(*toc);
|
||||
offset = iov[0].iov_len + iov[1].iov_len;
|
||||
|
||||
/* Reserve space for header */
|
||||
lseek(fdw, offset, SEEK_SET);
|
||||
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "data size %ju bytes, number of clusters "
|
||||
"%u, index length %zu bytes\n", sb.st_size,
|
||||
hdr.nblocks, iov[1].iov_len);
|
||||
|
||||
/* Init lzma encoder */
|
||||
if (lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT))
|
||||
errx(1, "Error loading LZMA preset");
|
||||
|
||||
filters[0].id = LZMA_FILTER_LZMA2;
|
||||
filters[0].options = &opt_lzma;
|
||||
filters[1].id = LZMA_VLI_UNKNOWN;
|
||||
|
||||
for(i = 0; i == 0 || ibuf != NULL; i++) {
|
||||
ibuf = readblock(fdr, ibuf, hdr.blksz);
|
||||
if (ibuf != NULL) {
|
||||
destlen = hdr.blksz*2;
|
||||
|
||||
ret = lzma_stream_encoder(&strm, filters,
|
||||
LZMA_CHECK_CRC32);
|
||||
if (ret != LZMA_OK) {
|
||||
if (ret == LZMA_MEMLIMIT_ERROR)
|
||||
errx(1, "can't compress data: "
|
||||
"LZMA_MEMLIMIT_ERROR");
|
||||
|
||||
errx(1, "can't compress data: "
|
||||
"LZMA compressor ERROR");
|
||||
}
|
||||
|
||||
strm.next_in = ibuf;
|
||||
strm.avail_in = hdr.blksz;
|
||||
strm.next_out = obuf;
|
||||
strm.avail_out = hdr.blksz*2;
|
||||
|
||||
ret = lzma_code(&strm, LZMA_FINISH);
|
||||
|
||||
if (ret != LZMA_STREAM_END) {
|
||||
/* Error */
|
||||
errx(1, "lzma_code FINISH failed, code=%d, "
|
||||
"pos(in=%zd, out=%zd)",
|
||||
ret,
|
||||
(hdr.blksz - strm.avail_in),
|
||||
(hdr.blksz*2 - strm.avail_out));
|
||||
}
|
||||
|
||||
destlen -= strm.avail_out;
|
||||
|
||||
lzma_end(&strm);
|
||||
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "cluster #%d, in %u bytes, "
|
||||
"out %u bytes\n", i, hdr.blksz, destlen);
|
||||
} else {
|
||||
destlen = USED_BLOCKSIZE - (offset % USED_BLOCKSIZE);
|
||||
memset(obuf, 0, destlen);
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "padding data with %u bytes"
|
||||
" so that file size is multiple of %d\n",
|
||||
destlen,
|
||||
USED_BLOCKSIZE);
|
||||
}
|
||||
if (write(fdw, obuf, destlen) < 0) {
|
||||
err(1, "write(%s)", oname);
|
||||
/* Not reached */
|
||||
}
|
||||
toc[i] = htobe64(offset);
|
||||
offset += destlen;
|
||||
}
|
||||
close(fdr);
|
||||
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "compressed data to %ju bytes, saved %lld "
|
||||
"bytes, %.2f%% decrease.\n", offset,
|
||||
(long long)(sb.st_size - offset),
|
||||
100.0 * (long long)(sb.st_size - offset) /
|
||||
(float)sb.st_size);
|
||||
|
||||
/* Convert to big endian */
|
||||
hdr.blksz = htonl(hdr.blksz);
|
||||
hdr.nblocks = htonl(hdr.nblocks);
|
||||
/* Write headers into pre-allocated space */
|
||||
lseek(fdw, 0, SEEK_SET);
|
||||
if (writev(fdw, iov, 2) < 0) {
|
||||
err(1, "writev(%s)", oname);
|
||||
/* Not reached */
|
||||
}
|
||||
cleanfile = NULL;
|
||||
close(fdw);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static char *
|
||||
readblock(int fd, char *ibuf, u_int32_t clstsize)
|
||||
{
|
||||
int numread;
|
||||
|
||||
bzero(ibuf, clstsize);
|
||||
numread = read(fd, ibuf, clstsize);
|
||||
if (numread < 0) {
|
||||
err(1, "read() failed");
|
||||
/* Not reached */
|
||||
}
|
||||
if (numread == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: mkulzma [-v] [-o outfile] [-s cluster_size] "
|
||||
"infile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void *
|
||||
safe_malloc(size_t size)
|
||||
{
|
||||
void *retval;
|
||||
|
||||
retval = malloc(size);
|
||||
if (retval == NULL) {
|
||||
err(1, "can't allocate memory");
|
||||
/* Not reached */
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
|
||||
if (cleanfile != NULL)
|
||||
unlink(cleanfile);
|
||||
}
|
@ -2,7 +2,8 @@
|
||||
|
||||
PROG= mkuzip
|
||||
MAN= mkuzip.8
|
||||
SRCS= mkuzip.c mkuz_blockcache.c mkuz_lzma.c mkuz_zlib.c
|
||||
|
||||
LIBADD= z
|
||||
LIBADD= z md lzma
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
97
usr.bin/mkuzip/mkuz_blockcache.c
Normal file
97
usr.bin/mkuzip/mkuz_blockcache.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <md5.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(MKUZ_DEBUG)
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "mkuz_blockcache.h"
|
||||
|
||||
struct mkuz_blkcache {
|
||||
struct mkuz_blkcache_hit hit;
|
||||
off_t data_offset;
|
||||
unsigned char digest[16];
|
||||
struct mkuz_blkcache *next;
|
||||
};
|
||||
|
||||
static struct mkuz_blkcache blkcache;
|
||||
|
||||
struct mkuz_blkcache_hit *
|
||||
mkuz_blkcache_regblock(int fd, uint32_t blkno, off_t offset, ssize_t len,
|
||||
void *data)
|
||||
{
|
||||
struct mkuz_blkcache *bcep;
|
||||
MD5_CTX mcontext;
|
||||
off_t data_offset;
|
||||
unsigned char mdigest[16];
|
||||
|
||||
data_offset = lseek(fd, 0, SEEK_CUR);
|
||||
if (data_offset < 0) {
|
||||
return (NULL);
|
||||
}
|
||||
MD5Init(&mcontext);
|
||||
MD5Update(&mcontext, data, len);
|
||||
MD5Final(mdigest, &mcontext);
|
||||
if (blkcache.hit.len == 0) {
|
||||
bcep = &blkcache;
|
||||
} else {
|
||||
for (bcep = &blkcache; bcep != NULL; bcep = bcep->next) {
|
||||
if (bcep->hit.len != len)
|
||||
continue;
|
||||
if (memcmp(mdigest, bcep->digest, sizeof(mdigest)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bcep != NULL) {
|
||||
#if defined(MKUZ_DEBUG)
|
||||
printf("cache hit %d, %d, %d\n", (int)bcep->hit.offset, (int)data_offset, (int)len);
|
||||
#endif
|
||||
return (&bcep->hit);
|
||||
}
|
||||
bcep = malloc(sizeof(struct mkuz_blkcache));
|
||||
if (bcep == NULL)
|
||||
return (NULL);
|
||||
memset(bcep, '\0', sizeof(struct mkuz_blkcache));
|
||||
bcep->next = blkcache.next;
|
||||
blkcache.next = bcep;
|
||||
}
|
||||
memcpy(bcep->digest, mdigest, sizeof(mdigest));
|
||||
bcep->data_offset = data_offset;
|
||||
bcep->hit.offset = offset;
|
||||
bcep->hit.len = len;
|
||||
bcep->hit.blkno = blkno;
|
||||
return (NULL);
|
||||
}
|
36
usr.bin/mkuzip/mkuz_blockcache.h
Normal file
36
usr.bin/mkuzip/mkuz_blockcache.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct mkuz_blkcache_hit {
|
||||
uint64_t offset;
|
||||
ssize_t len;
|
||||
uint32_t blkno;
|
||||
};
|
||||
|
||||
struct mkuz_blkcache_hit *mkuz_blkcache_regblock(int, uint32_t, off_t, ssize_t,
|
||||
void *);
|
50
usr.bin/mkuzip/mkuz_cloop.h
Normal file
50
usr.bin/mkuzip/mkuz_cloop.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* CLOOP format and related constants */
|
||||
|
||||
/*
|
||||
* Integer values (block size, number of blocks, offsets)
|
||||
* are stored in big-endian (network) order on disk.
|
||||
*/
|
||||
|
||||
#define CLOOP_MAGIC_LEN 128
|
||||
#define CLOOP_OFS_COMPR 0x0b
|
||||
#define CLOOP_OFS_VERSN (CLOOP_OFS_COMPR + 1)
|
||||
|
||||
#define CLOOP_MAJVER_2 '2'
|
||||
#define CLOOP_MAJVER_3 '3'
|
||||
|
||||
#define CLOOP_COMP_LIBZ 'V'
|
||||
#define CLOOP_COMP_LZMA 'L'
|
||||
|
||||
struct cloop_header {
|
||||
char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
};
|
110
usr.bin/mkuzip/mkuz_lzma.c
Normal file
110
usr.bin/mkuzip/mkuz_lzma.c
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* Copyright (c) 2011 Aleksandr Rybalko <ray@ddteam.net>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lzma.h>
|
||||
|
||||
#include "mkuzip.h"
|
||||
#include "mkuz_lzma.h"
|
||||
|
||||
#define USED_BLOCKSIZE DEV_BSIZE
|
||||
|
||||
struct mkuz_lzma {
|
||||
lzma_filter filters[2];
|
||||
lzma_options_lzma opt_lzma;
|
||||
lzma_stream strm;
|
||||
char *obuf;
|
||||
uint32_t blksz;
|
||||
};
|
||||
|
||||
static struct mkuz_lzma ulzma = {.strm = LZMA_STREAM_INIT};
|
||||
|
||||
void *
|
||||
mkuz_lzma_init(uint32_t blksz)
|
||||
{
|
||||
if (blksz % USED_BLOCKSIZE != 0) {
|
||||
errx(1, "cluster size should be multiple of %d",
|
||||
USED_BLOCKSIZE);
|
||||
/* Not reached */
|
||||
}
|
||||
if (blksz > MAXPHYS) {
|
||||
errx(1, "cluster size is too large");
|
||||
/* Not reached */
|
||||
}
|
||||
ulzma.obuf = mkuz_safe_malloc(blksz * 2);
|
||||
|
||||
/* Init lzma encoder */
|
||||
if (lzma_lzma_preset(&ulzma.opt_lzma, LZMA_PRESET_DEFAULT))
|
||||
errx(1, "Error loading LZMA preset");
|
||||
|
||||
ulzma.filters[0].id = LZMA_FILTER_LZMA2;
|
||||
ulzma.filters[0].options = &ulzma.opt_lzma;
|
||||
ulzma.filters[1].id = LZMA_VLI_UNKNOWN;
|
||||
|
||||
ulzma.blksz = blksz;
|
||||
|
||||
return (ulzma.obuf);
|
||||
}
|
||||
|
||||
void
|
||||
mkuz_lzma_compress(const char *ibuf, uint32_t *destlen)
|
||||
{
|
||||
lzma_ret ret;
|
||||
|
||||
ret = lzma_stream_encoder(&ulzma.strm, ulzma.filters, LZMA_CHECK_CRC32);
|
||||
if (ret != LZMA_OK) {
|
||||
if (ret == LZMA_MEMLIMIT_ERROR)
|
||||
errx(1, "can't compress data: LZMA_MEMLIMIT_ERROR");
|
||||
|
||||
errx(1, "can't compress data: LZMA compressor ERROR");
|
||||
}
|
||||
|
||||
ulzma.strm.next_in = ibuf;
|
||||
ulzma.strm.avail_in = ulzma.blksz;
|
||||
ulzma.strm.next_out = ulzma.obuf;
|
||||
ulzma.strm.avail_out = ulzma.blksz * 2;
|
||||
|
||||
ret = lzma_code(&ulzma.strm, LZMA_FINISH);
|
||||
|
||||
if (ret != LZMA_STREAM_END) {
|
||||
/* Error */
|
||||
errx(1, "lzma_code FINISH failed, code=%d, pos(in=%zd, "
|
||||
"out=%zd)", ret, (ulzma.blksz - ulzma.strm.avail_in),
|
||||
(ulzma.blksz * 2 - ulzma.strm.avail_out));
|
||||
}
|
||||
|
||||
lzma_end(&ulzma.strm);
|
||||
|
||||
*destlen = (ulzma.blksz * 2) - ulzma.strm.avail_out;
|
||||
}
|
42
usr.bin/mkuzip/mkuz_lzma.h
Normal file
42
usr.bin/mkuzip/mkuz_lzma.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* Copyright (c) 2011 Aleksandr Rybalko <ray@ddteam.net>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Format L3.0, since we move to XZ API */
|
||||
#define CLOOP_MAGIC_LZMA \
|
||||
"#!/bin/sh\n" \
|
||||
"#L3.0\n" \
|
||||
"n=uncompress\n" \
|
||||
"m=geom_$n\n" \
|
||||
"(kldstat -m $m 2>&-||kldload $m)>&-&&" \
|
||||
"mount_cd9660 /dev/`mdconfig -af $0`.$n $1\n" \
|
||||
"exit $?\n"
|
||||
#define DEFAULT_SUFX_LZMA ".ulzma"
|
||||
|
||||
void *mkuz_lzma_init(uint32_t);
|
||||
void mkuz_lzma_compress(const char *, uint32_t *);
|
81
usr.bin/mkuzip/mkuz_zlib.c
Normal file
81
usr.bin/mkuzip/mkuz_zlib.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "mkuzip.h"
|
||||
#include "mkuz_zlib.h"
|
||||
|
||||
struct mkuz_zlib {
|
||||
char *obuf;
|
||||
uLongf oblen;
|
||||
uint32_t blksz;
|
||||
};
|
||||
|
||||
static struct mkuz_zlib uzip;
|
||||
|
||||
void *
|
||||
mkuz_zlib_init(uint32_t blksz)
|
||||
{
|
||||
if (blksz % DEV_BSIZE != 0) {
|
||||
errx(1, "cluster size should be multiple of %d",
|
||||
DEV_BSIZE);
|
||||
/* Not reached */
|
||||
}
|
||||
if (compressBound(blksz) > MAXPHYS) {
|
||||
errx(1, "cluster size is too large");
|
||||
/* Not reached */
|
||||
}
|
||||
uzip.oblen = compressBound(blksz);
|
||||
uzip.obuf = mkuz_safe_malloc(uzip.oblen);
|
||||
uzip.blksz = blksz;
|
||||
|
||||
return (uzip.obuf);
|
||||
}
|
||||
|
||||
void
|
||||
mkuz_zlib_compress(const char *ibuf, uint32_t *destlen)
|
||||
{
|
||||
uLongf destlen_z;
|
||||
|
||||
destlen_z = uzip.oblen;
|
||||
if (compress2(uzip.obuf, &destlen_z, ibuf, uzip.blksz,
|
||||
Z_BEST_COMPRESSION) != Z_OK) {
|
||||
errx(1, "can't compress data: compress2() "
|
||||
"failed");
|
||||
/* Not reached */
|
||||
}
|
||||
|
||||
*destlen = (uint32_t)destlen_z;
|
||||
}
|
36
usr.bin/mkuzip/mkuz_zlib.h
Normal file
36
usr.bin/mkuzip/mkuz_zlib.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define DEFAULT_SUFX_ZLIB ".uzip"
|
||||
|
||||
#define CLOOP_MAGIC_ZLIB "#!/bin/sh\n#V2.0 Format\n" \
|
||||
"(kldstat -qm g_uzip||kldload geom_uzip)>&-&&" \
|
||||
"mount_cd9660 /dev/`mdconfig -af $0`.uzip $1\nexit $?\n"
|
||||
|
||||
void *mkuz_zlib_init(uint32_t);
|
||||
void mkuz_zlib_compress(const char *, uint32_t *);
|
@ -1,9 +1,27 @@
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\" "THE BEER-WARE LICENSE" (Revision 42):
|
||||
.\" <sobomax@FreeBSD.org> wrote this file. As long as you retain this notice you
|
||||
.\" can do whatever you want with this stuff. If we meet some day, and you think
|
||||
.\" this stuff is worth it, you can buy me a beer in return. Maxim Sobolev
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\"-
|
||||
.\" Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
@ -39,7 +57,9 @@ works in two phases:
|
||||
An
|
||||
.Ar infile
|
||||
image is split into clusters; each cluster is compressed using
|
||||
.Xr zlib 3 .
|
||||
.Xr zlib 3
|
||||
or
|
||||
.Xr lzma 3 .
|
||||
.It
|
||||
The resulting set of compressed clusters along with headers that allow
|
||||
locating each individual cluster is written to the output file.
|
||||
@ -51,7 +71,23 @@ The options are:
|
||||
Name of the output file
|
||||
.Ar outfile .
|
||||
The default is to use the input name with the suffix
|
||||
.Pa .uzip .
|
||||
.Pa .uzip
|
||||
for the
|
||||
.Xr zlib 3
|
||||
compression or
|
||||
.Pa .ulzma
|
||||
for the
|
||||
.Xr lzma 3 .
|
||||
.It Fl L
|
||||
Use
|
||||
.Xr lzma 3
|
||||
compression algorithm instead of the default
|
||||
.Xr zlib 3 .
|
||||
The
|
||||
.Xr lzma 3
|
||||
provides noticeable better compression levels on the same data set
|
||||
at the expense of much slower compression speed (10-20x) and somewhat slower
|
||||
decompression (2-3x).
|
||||
.It Fl s Ar cluster_size
|
||||
Split the image into clusters of
|
||||
.Ar cluster_size
|
||||
@ -61,6 +97,27 @@ The
|
||||
should be a multiple of 512 bytes.
|
||||
.It Fl v
|
||||
Display verbose messages.
|
||||
.It Fl Z
|
||||
Disable zero-blocks detection and elimination.
|
||||
When this option is set, the
|
||||
.Nm
|
||||
would compress empty blocks (i.e. clusters that consist of only zero bytes)
|
||||
just as it would any other block.
|
||||
When the option is not set, the
|
||||
.Nm
|
||||
detects such blocks and skips them from the output.
|
||||
Setting
|
||||
.Fl Z
|
||||
results is slight increase of compressed image size, typically less than 0.1%
|
||||
of a final size of the compressed image.
|
||||
.It Fl d
|
||||
Enable de-duplication.
|
||||
When the option is enabled the
|
||||
.Nm
|
||||
detects identical blocks in the input and replaces each subsequent occurence
|
||||
of such block with pointer to the very first one in the output.
|
||||
Setting this option results is moderate decrease of compressed image size,
|
||||
typically around 3-5% of a final size of the compressed image.
|
||||
.El
|
||||
.Sh NOTES
|
||||
The compression ratio largely depends on the cluster size used.
|
||||
@ -92,11 +149,20 @@ disk device using
|
||||
and automatically mount it using
|
||||
.Xr mount_cd9660 8
|
||||
on the mount point provided as the first argument to the script.
|
||||
.Pp
|
||||
The de-duplication is a
|
||||
.Fx
|
||||
specific feature and while it does not require any changes to on-disk
|
||||
compressed image format, however it did require some matching changes to the
|
||||
.Xr geom_uzip 4
|
||||
to handle resulting images correctly.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr gzip 1 ,
|
||||
.Xr xz 1 ,
|
||||
.Xr zlib 3 ,
|
||||
.Xr lzma 3 ,
|
||||
.Xr geom 4 ,
|
||||
.Xr geom_uzip 4 ,
|
||||
.Xr md 4 ,
|
||||
|
@ -1,15 +1,33 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <sobomax@FreeBSD.ORG> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Maxim Sobolev
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* $FreeBSD$
|
||||
* 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 AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/endian.h>
|
||||
@ -17,7 +35,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <zlib.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
@ -26,18 +44,44 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CLSTSIZE 16384
|
||||
#define DEFAULT_SUFX ".uzip"
|
||||
#include "mkuzip.h"
|
||||
#include "mkuz_cloop.h"
|
||||
#include "mkuz_blockcache.h"
|
||||
#include "mkuz_zlib.h"
|
||||
#include "mkuz_lzma.h"
|
||||
|
||||
#define CLOOP_MAGIC_LEN 128
|
||||
static char CLOOP_MAGIC_START[] = "#!/bin/sh\n#V2.0 Format\n"
|
||||
"(kldstat -qm g_uzip||kldload geom_uzip)>&-&&"
|
||||
"mount_cd9660 /dev/`mdconfig -af $0`.uzip $1\nexit $?\n";
|
||||
#define DEFINE_RAW_METHOD(func, rval, args...) typedef rval (*func##_t)(args)
|
||||
|
||||
#define DEFAULT_CLSTSIZE 16384
|
||||
|
||||
DEFINE_RAW_METHOD(f_init, void *, uint32_t);
|
||||
DEFINE_RAW_METHOD(f_compress, void, const char *, uint32_t *);
|
||||
|
||||
struct mkuz_format {
|
||||
const char *magic;
|
||||
const char *default_sufx;
|
||||
f_init_t f_init;
|
||||
f_compress_t f_compress;
|
||||
};
|
||||
|
||||
static struct mkuz_format uzip_fmt = {
|
||||
.magic = CLOOP_MAGIC_ZLIB,
|
||||
.default_sufx = DEFAULT_SUFX_ZLIB,
|
||||
.f_init = &mkuz_zlib_init,
|
||||
.f_compress = &mkuz_zlib_compress
|
||||
};
|
||||
|
||||
static struct mkuz_format ulzma_fmt = {
|
||||
.magic = CLOOP_MAGIC_LZMA,
|
||||
.default_sufx = DEFAULT_SUFX_LZMA,
|
||||
.f_init = &mkuz_lzma_init,
|
||||
.f_compress = &mkuz_lzma_compress
|
||||
};
|
||||
|
||||
static char *readblock(int, char *, u_int32_t);
|
||||
static void usage(void);
|
||||
static void *safe_malloc(size_t);
|
||||
static void cleanup(void);
|
||||
static int memvcmp(const void *, unsigned char, size_t);
|
||||
|
||||
static char *cleanfile = NULL;
|
||||
|
||||
@ -45,24 +89,24 @@ int main(int argc, char **argv)
|
||||
{
|
||||
char *iname, *oname, *obuf, *ibuf;
|
||||
uint64_t *toc;
|
||||
int fdr, fdw, i, opt, verbose, tmp;
|
||||
int fdr, fdw, i, opt, verbose, no_zcomp, tmp, en_dedup;
|
||||
struct iovec iov[2];
|
||||
struct stat sb;
|
||||
uLongf destlen;
|
||||
uint64_t offset;
|
||||
struct cloop_header {
|
||||
char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
} hdr;
|
||||
uint32_t destlen;
|
||||
uint64_t offset, last_offset;
|
||||
struct cloop_header hdr;
|
||||
struct mkuz_blkcache_hit *chit;
|
||||
const struct mkuz_format *handler;
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
hdr.blksz = CLSTSIZE;
|
||||
strcpy(hdr.magic, CLOOP_MAGIC_START);
|
||||
hdr.blksz = DEFAULT_CLSTSIZE;
|
||||
oname = NULL;
|
||||
verbose = 0;
|
||||
no_zcomp = 0;
|
||||
en_dedup = 0;
|
||||
handler = &uzip_fmt;
|
||||
|
||||
while((opt = getopt(argc, argv, "o:s:v")) != -1) {
|
||||
while((opt = getopt(argc, argv, "o:s:vZdL")) != -1) {
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
oname = optarg;
|
||||
@ -75,15 +119,6 @@ int main(int argc, char **argv)
|
||||
optarg);
|
||||
/* Not reached */
|
||||
}
|
||||
if (tmp % DEV_BSIZE != 0) {
|
||||
errx(1, "cluster size should be multiple of %d",
|
||||
DEV_BSIZE);
|
||||
/* Not reached */
|
||||
}
|
||||
if (compressBound(tmp) > MAXPHYS) {
|
||||
errx(1, "cluster size is too large");
|
||||
/* Not reached */
|
||||
}
|
||||
hdr.blksz = tmp;
|
||||
break;
|
||||
|
||||
@ -91,6 +126,18 @@ int main(int argc, char **argv)
|
||||
verbose = 1;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
no_zcomp = 1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
en_dedup = 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
handler = &ulzma_fmt;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* Not reached */
|
||||
@ -104,17 +151,26 @@ int main(int argc, char **argv)
|
||||
/* Not reached */
|
||||
}
|
||||
|
||||
strcpy(hdr.magic, handler->magic);
|
||||
|
||||
if (en_dedup != 0) {
|
||||
hdr.magic[CLOOP_OFS_VERSN] = CLOOP_MAJVER_3;
|
||||
hdr.magic[CLOOP_OFS_COMPR] =
|
||||
tolower(hdr.magic[CLOOP_OFS_COMPR]);
|
||||
}
|
||||
|
||||
obuf = handler->f_init(hdr.blksz);
|
||||
|
||||
iname = argv[0];
|
||||
if (oname == NULL) {
|
||||
asprintf(&oname, "%s%s", iname, DEFAULT_SUFX);
|
||||
asprintf(&oname, "%s%s", iname, handler->default_sufx);
|
||||
if (oname == NULL) {
|
||||
err(1, "can't allocate memory");
|
||||
/* Not reached */
|
||||
}
|
||||
}
|
||||
|
||||
obuf = safe_malloc(compressBound(hdr.blksz));
|
||||
ibuf = safe_malloc(hdr.blksz);
|
||||
ibuf = mkuz_safe_malloc(hdr.blksz);
|
||||
|
||||
signal(SIGHUP, exit);
|
||||
signal(SIGINT, exit);
|
||||
@ -152,7 +208,7 @@ int main(int argc, char **argv)
|
||||
"of %d, padding data\n", hdr.blksz);
|
||||
hdr.nblocks++;
|
||||
}
|
||||
toc = safe_malloc((hdr.nblocks + 1) * sizeof(*toc));
|
||||
toc = mkuz_safe_malloc((hdr.nblocks + 1) * sizeof(*toc));
|
||||
|
||||
fdw = open(oname, O_WRONLY | O_TRUNC | O_CREAT,
|
||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
@ -177,40 +233,73 @@ int main(int argc, char **argv)
|
||||
"%u, index length %zu bytes\n", sb.st_size,
|
||||
hdr.nblocks, iov[1].iov_len);
|
||||
|
||||
last_offset = 0;
|
||||
for(i = 0; i == 0 || ibuf != NULL; i++) {
|
||||
ibuf = readblock(fdr, ibuf, hdr.blksz);
|
||||
if (ibuf != NULL) {
|
||||
destlen = compressBound(hdr.blksz);
|
||||
if (compress2(obuf, &destlen, ibuf, hdr.blksz,
|
||||
Z_BEST_COMPRESSION) != Z_OK) {
|
||||
errx(1, "can't compress data: compress2() "
|
||||
"failed");
|
||||
/* Not reached */
|
||||
if (no_zcomp == 0 && \
|
||||
memvcmp(ibuf, '\0', hdr.blksz) != 0) {
|
||||
/* All zeroes block */
|
||||
destlen = 0;
|
||||
} else {
|
||||
handler->f_compress(ibuf, &destlen);
|
||||
}
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "cluster #%d, in %u bytes, "
|
||||
"out %lu bytes\n", i, hdr.blksz, destlen);
|
||||
} else {
|
||||
destlen = DEV_BSIZE - (offset % DEV_BSIZE);
|
||||
memset(obuf, 0, destlen);
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "padding data with %lu bytes so "
|
||||
"that file size is multiple of %d\n", destlen,
|
||||
DEV_BSIZE);
|
||||
fprintf(stderr, "padding data with %lu bytes "
|
||||
"so that file size is multiple of %d\n",
|
||||
(u_long)destlen, DEV_BSIZE);
|
||||
}
|
||||
if (write(fdw, obuf, destlen) < 0) {
|
||||
err(1, "write(%s)", oname);
|
||||
/* Not reached */
|
||||
if (destlen > 0 && en_dedup != 0) {
|
||||
chit = mkuz_blkcache_regblock(fdw, i, offset, destlen,
|
||||
obuf);
|
||||
/*
|
||||
* There should be at least one non-empty block
|
||||
* between us and the backref'ed offset, otherwise
|
||||
* we won't be able to parse that sequence correctly
|
||||
* as it would be indistinguishible from another
|
||||
* empty block.
|
||||
*/
|
||||
if (chit != NULL && chit->offset == last_offset) {
|
||||
chit = NULL;
|
||||
}
|
||||
} else {
|
||||
chit = NULL;
|
||||
}
|
||||
if (chit != NULL) {
|
||||
toc[i] = htobe64(chit->offset);
|
||||
} else {
|
||||
if (destlen > 0 && write(fdw, obuf, destlen) < 0) {
|
||||
err(1, "write(%s)", oname);
|
||||
/* Not reached */
|
||||
}
|
||||
toc[i] = htobe64(offset);
|
||||
last_offset = offset;
|
||||
offset += destlen;
|
||||
}
|
||||
if (ibuf != NULL && verbose != 0) {
|
||||
fprintf(stderr, "cluster #%d, in %u bytes, "
|
||||
"out len=%lu offset=%lu", i, hdr.blksz,
|
||||
chit == NULL ? (u_long)destlen : 0,
|
||||
(u_long)be64toh(toc[i]));
|
||||
if (chit != NULL) {
|
||||
fprintf(stderr, " (backref'ed to #%d)",
|
||||
chit->blkno);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
}
|
||||
toc[i] = htobe64(offset);
|
||||
offset += destlen;
|
||||
}
|
||||
close(fdr);
|
||||
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "compressed data to %ju bytes, saved %lld "
|
||||
"bytes, %.2f%% decrease.\n", offset, (long long)(sb.st_size - offset),
|
||||
100.0 * (long long)(sb.st_size - offset) / (float)sb.st_size);
|
||||
"bytes, %.2f%% decrease.\n", offset,
|
||||
(long long)(sb.st_size - offset),
|
||||
100.0 * (long long)(sb.st_size - offset) /
|
||||
(float)sb.st_size);
|
||||
|
||||
/* Convert to big endian */
|
||||
hdr.blksz = htonl(hdr.blksz);
|
||||
@ -248,12 +337,13 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: mkuzip [-v] [-o outfile] [-s cluster_size] infile\n");
|
||||
fprintf(stderr, "usage: mkuzip [-vZdL] [-o outfile] [-s cluster_size] "
|
||||
"infile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void *
|
||||
safe_malloc(size_t size)
|
||||
void *
|
||||
mkuz_safe_malloc(size_t size)
|
||||
{
|
||||
void *retval;
|
||||
|
||||
@ -272,3 +362,12 @@ cleanup(void)
|
||||
if (cleanfile != NULL)
|
||||
unlink(cleanfile);
|
||||
}
|
||||
|
||||
static int
|
||||
memvcmp(const void *memory, unsigned char val, size_t size)
|
||||
{
|
||||
const u_char *mm;
|
||||
|
||||
mm = (const u_char *)memory;
|
||||
return (*mm == val) && memcmp(mm, mm + 1, size - 1) == 0;
|
||||
}
|
||||
|
29
usr.bin/mkuzip/mkuzip.h
Normal file
29
usr.bin/mkuzip/mkuzip.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
void *mkuz_safe_malloc(size_t);
|
@ -2,7 +2,7 @@
|
||||
|
||||
NO_WERROR=
|
||||
PROG= truss
|
||||
SRCS= cloudabi.c main.c setup.c syscalls.c
|
||||
SRCS= main.c setup.c syscalls.c
|
||||
|
||||
LIBADD= sysdecode
|
||||
|
||||
|
@ -31,11 +31,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/armreg.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sysdecode.h>
|
||||
|
||||
#include "cloudabi.h"
|
||||
#include "truss.h"
|
||||
|
||||
static int
|
||||
@ -74,8 +72,6 @@ aarch64_cloudabi64_fetch_retval(struct trussinfo *trussinfo, long *retval,
|
||||
retval[0] = regs.x[0];
|
||||
retval[1] = regs.x[1];
|
||||
*errorp = (regs.spsr & PSR_C) != 0;
|
||||
if (*errorp)
|
||||
retval[0] = cloudabi_convert_errno(retval[0]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/psl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sysdecode.h>
|
||||
|
||||
#include "cloudabi.h"
|
||||
#include "truss.h"
|
||||
|
||||
static int
|
||||
@ -83,8 +81,6 @@ amd64_cloudabi64_fetch_retval(struct trussinfo *trussinfo, long *retval,
|
||||
retval[0] = regs.r_rax;
|
||||
retval[1] = regs.r_rdx;
|
||||
*errorp = (regs.r_rflags & PSL_C) != 0;
|
||||
if (*errorp)
|
||||
retval[0] = cloudabi_convert_errno(retval[0]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -83,28 +83,12 @@ amd64_linux32_fetch_args(struct trussinfo *trussinfo, u_int narg)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Linux syscalls return negative errno's, we do positive and map them
|
||||
*/
|
||||
static const int bsd_to_linux_errno[] = {
|
||||
-0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
|
||||
-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
|
||||
-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
|
||||
-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
|
||||
-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
|
||||
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
|
||||
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
|
||||
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
|
||||
-6,
|
||||
};
|
||||
|
||||
static int
|
||||
amd64_linux32_fetch_retval(struct trussinfo *trussinfo, long *retval,
|
||||
int *errorp)
|
||||
{
|
||||
struct reg regs;
|
||||
lwpid_t tid;
|
||||
size_t i;
|
||||
|
||||
tid = trussinfo->curthread->tid;
|
||||
if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) {
|
||||
@ -117,17 +101,6 @@ amd64_linux32_fetch_retval(struct trussinfo *trussinfo, long *retval,
|
||||
*errorp = !!(regs.r_rflags & PSL_C);
|
||||
if (*errorp)
|
||||
retval[0] = (int)retval[0];
|
||||
|
||||
if (*errorp) {
|
||||
for (i = 0; i < nitems(bsd_to_linux_errno); i++) {
|
||||
if (retval[0] == bsd_to_linux_errno[i]) {
|
||||
retval[0] = i;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: How to handle unknown errors? */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user